Antialiasing 101

HTML5 Rocks

소개

안티앨리어싱은 스크린 상에서 깔끔한 텍스트와 부드러운 벡터 형태를 가지게 된 근본적인 이유인데도 불구하고 웹 그래픽스에서 알려지지 못한 영웅과도 같습니다. 실제로 안티앨리어싱의 접근 방법 몇가지는 오늘날의 브라우저에서 텍스트를 렌더링할 때 가장 분명하게 사용되고 있습니다. 안티앨리어싱의 알고리즘을 변경하면 예상치못한 시각적인 결과물을 만들어 낼 수도 있습니다. 이 글에서는 안티앨리어싱을 살펴보고 픽셀이 어떻게 그려지는지를 확인해볼 것입니다.

모든 스크린은 우리가 잘 알고 있듯이 픽셀들로 구성되어 있습니다. 블록들의 거대한 그리드이며 각각이 적색과 녹색 그리고 청색 요소들(RGB)을 포함하고 있습니다. 멀리서 이미지, 텍스트 그리고 아이콘들을 볼 수 있지만 실제로 가까이서 보면 RGB 요소들의 그리드이며 모든 것이 어떻게 구성되어 있는지 확인할 수 있습니다.

Figure 1 - 스크린에서 확대한 픽셀들. 각 픽셀들은 적색, 녹색 그리고 청색 요소들을 가지고 있습니다.

안티앨리어싱

그러므로 도형의 벡터를 그리면서 픽셀의 "일부분"를 통해 전달할 때 무엇이 일어날까요? 우리가 하얀색 배경 위에 검은색으로 그리는 도형을 가정해 보도록 하겠습니다. 저 픽셀을 전부 색칠해야할까요? 색칠을 한다면 어떤 색상으로 해야할까요? 검정색, 회색 혹은 또 다른 색?

안티앨리어싱의 과정은 픽셀을 채울 때 어떠한 컬러를 사용할지를 결정합니다. 가장 단순한 버전은 그레이스케일 안티앨리어싱(Grayscale antialiasing)이며 픽셀들의 세가지 요소를 동동하게 취급합니다. 그러므로 픽셀이 절반을 차지하고 — 단순함을 유지하기 위해 잠시 하얀 바탕 위에 검정색 텍스트가 있다고 가정해봅시다. — 여러분은 각 요소가 절반의 밝기로 설정할 것입니다. (전 제가 확실히 처리했다는 것을 알고 있습니다.) 그러나 사실은 그보다는 더 복잡합니다. (이를 설명하려면) 여러분이 절대로 정확한 값을 설정하지 않을 것 같은 감마에 대해 설명해야 합니다.) 물론 그것이 약간 까다롭게 만들긴 히자만 이것은 논의 주제에 대한 소개이므로 여기서 더 이상 깊이 다루지는 않겠습니다. 여기서 알아야 하는 중요한 점은 그레이스케일 안티앨리어싱은 픽셀 수준에서 처리되며 사실 더 많은 것을 할 수 있다는 것입니다.

Figure 2 - 안티앨리어싱 vs 선명한 윤곽들

Figure 2에서 똑같이 그려진 삼각형을 볼 수 있겠지만 좌측은 안티앨리어싱이 된 것이고 우측은 그렇지 않은 것입니다. 보이는 바와 같이 안티앨리어싱은 삼각형이 픽셀의 일부를 통과할 때만 픽셀들이 회색 음영들일 수 있도록 합니다. 그러나 쓰지 못할 때는 픽셀들은 완전한 검정색이나 완전한 하얀색으로 칠해지고 도형은 (픽셀 수준에서) 들쭉날쭉하게 보일 것입니다.

텍스트 렌더링

브라우저가 본질적으로는 벡터 형태인 텍스트를 렌더링할 때마다 '텍스트의 글자들이 픽셀들의 일부들만 채워지므로 그러한 픽셀들을 어떻게 채울 것인지에 대한 전략을 필요로 하게 되는' 동일한 문제에 직면하게 됩니다. 이상적으로 우리가 원하는 것은 텍스트가 더 즐겁고 읽기 쉽게 안티앨리어싱이 되는 것입니다.

그러나 그레이스케일 방식은 안티앨리어싱을 다루기 위한 단 한가지 방식을 나타낼 뿐입니다. 픽셀의 RGB 요소들을 어떻게 가능하게 하느냐에 따라 좀 더 선택 가능한 방식들이 종종 사용됩니다. 그 과정을 서브픽셀 안티앨리어싱(Subpixel antialiasing)이라 부르며 몇년간 마이크로스프트의 클리어타입(ClearType)팀은 이를 진행하는데 특히 아주 많은 시간과 노력을 투자했습니다. 이는 이제 훨씬 더 많고 폭넓게 사용되고 있으며 다소 차이는 있지만 주요 브라우저 모두가 이를 사용하고 있습니다.

먼저 실제로는 적색, 녹색 그리고 청색 요소로 분리되어 구성된 각 픽셀들을 우리가 알고 있으므로 문제의 이러한 각 요소들이 얼마나 많이 픽셀에 대해 "켜져 있는지"를 검출합니다. 이 과정을 종종 "화면 수평 해상도의 삼중결합(Tripling the horizontal resolution of the screen)"이라고 기술되며 이는 각 픽셀이 실제로는 하나의 유닛이 아니라 옆으로 나란히 놓여진 3개의 분리된 요소들이라는 사실에 의거합니다.

Figure 3 - 그레이스케일 앨리어싱 vs 서브픽셀 안티앨리어싱

위의 Figure 3에서 좌측은 각 요소들을 동등하게 다루고 있으며 각각의 켜고 끔이 동일함(Grayscale)을 알 수 있습니다. 그러나 우측을 보면 서브픽셀(Subpixel) 방식을 사용하여 각 요소(적색, 녹색 그리고 청색)가 그려지고 있는 모양 위에 얼마나 덮어쓰여지고 있는지에 따라 다르게 될 수 있다는 것을 알 수 있습니다.

그러나 흔히 말하듯이 인간의 시각은 실제로 적색, 녹색 그리고 청색 빛이 얼마나 동일한지 가중치를 두지 않습니다. 반면에 적색이나 청색보다 녹색에 훨씬 더 민감하며 이는 그레이스케일 안티앨리어싱을 넘어서는 뚜렷한 장점이 있다는 것을 의미하므로 Darel Rex Finley이 쓴 것처럼 각 요소를 분리되도록 하는 것이 실제로 명료성을 3배로 개선하지는 않을 것입니다. 서브픽셀 안티앨리어싱은 확실히 유익하고 엄격하며 이는 텍스트를 그레이스케일을 사용했을 때보다 더 깔끔하게 볼 수 있다는 것을 의미합니다.

Figure 4 - 서브픽셀 안티앨리어싱 텍스트. 픽셀의 개별적인 요소들은 전반적인 효과를 만들어 낼 수 있도록 합니다.

본론으로 들어갑시다

이 모든 것들이 개발자로써의 우리에게는 어떠한 의미가 있을까요? 자, 크롬의 관점에서 볼 때 최소한 그레이스케일과 서브픽셀 안티앨리어싱 모두를 혼용하여 텍스트를 렌더링하며 무엇을 쓸 지는 몇가지 기준들에 의존적입니다. 그러나 설명 전에 실행 시의 주요 기준인 레이어에 대해 조금 이해가 필요합니다. 만약 레이어에 대해 이해하지 못하고 크롬 내부에서 그들이 어떻게 사용되지는지를 알 지 못한다면 Tom Wiltzius이 쓴 이 주제에 대한 환상적인 설명을 반드시 먼저 읽어보시기 바랍니다.

여러분이 레이어에 대해 친숙하거나 혹은 그에 관해 막 읽어보았다고 가정하고 계속해 보도록 하겠습니다. 만약 하드웨어 합성(Compositing)이 페이지에 대해 가능하고 루트 레이어(Root layer)아닌 레이어 위에 텍스트 컨텐츠가 있다면 기본적으로 그레이스케일 안티앨리어싱을 사용하여 렌더링될 것입니다. 개발자들은 가끔 엘리먼트들을 그 엘리먼트들의 (루트가 아닌) 레이어 자체에 (translateZ와 같은) 핵(Hack)을 적용할 수 있는지에 대해 신경쓰고는 합니다. 가끔 개발자들은 자바스크립트나 CSS를 통해 텍스트 렌더링을 서브픽셀에서 그레이스케일로 변경하는 "새로운 레이어"를 즉시 발생하도록 적용하고는 하며 만약 렌더링이 어떠한 것으로 변경이 발생하였는지 알지 못한다면 혼란스러울 수 있습니다. 그러나 만약 텍스트가 루트 레이어에 있다면 그것은 서브픽셀 안티앨리어싱으로 렌더링될 것이며 따라서 훨씬 더 깔끔하게 읽을 수 있을 것입니다.

그러나 웹의 다른 모든 것과 비슷하게도 이는 변화 속에 있습니다. 크롬에서 서브픽셀 안티앨리어싱은 루트가 아닌 레이어의 텍스트에서 가능하며 3가지 기준을 만족하는 레이어를 제공합니다. 이 기준들은 오늘날 적용되고 있다고 언급할만한 가치가 있습니다만 이는 변경될 수 있으며 시간이 지난 뒤에도 가능한 더 많은 경우들을 알 수 있기를 바랄 것입니다. 이에 대한 현재의 기준들은 다음과 같습니다.

  1. 레이어가 완전하게 불투명한 색상을 가지고 있습니다. border-radius나 기본값이 아닌 background-clip 값들의 사용은 불투명한 것처럼 취급되는 레이어를 발생시키며 텍스트 렌더링은 그레이스케일 안티앨리어싱으로 되돌아갑니다.
  2. 레이어는 레이어에 적용하기 위한 항등 변환(identity transform)이나 적분 이동(integral translation) 중 하나를 가질 수 있습니다. 적분에 의해 반올림값을 의도할 수 있습니다. 따라서 예를 들어 translate(20.2px, 30px)는 x 요소 20.2px인 비적분 값이므로 그레이스케일 안티앨리어싱을 발생합니다. 항등 변환은 단순하게 기본적으로 적용된 것에 더 이상의 추가 회전, 이동(translation) 혹은 확대/축소(Scale)이 없다는 것을 의미합니다.
  3. 레이어는 1.0의 투명도(Opacity)를 가집니다. 투명도의 어떤 변화라도 서브픽셀에서 그레이스케일로 안티앨리어싱을 변경시킬 것입니다.
Figure 5 - 적용 전후: 그레이스케일 vs 서브픽셀. 텍스트 우측편의 색깔있는 가장자리를 주의해보시기 바랍니다.

끝으로 주의할 것 한가지는 CSS 애니메이션의 적용은 새로운 레이어의 생성을 생성할 것이며 requestAnimationFrame의 사용은 그렇지 않다는 점입니다. 몇몇 개발자에게 텍스트 렌더링의 차이점들은 묵시적으로 CSS 애니메이션의 사용을 못하게 합니다. 그러므로 텍스트 렌더링의 차이점 때문에 자바스크립트로 엘리먼트를 애니메이션한다면 이 업데이트가 문제를 수정해주는지에 대해 확인해보시기 바랍니다!

여기까지가 크롬이 커버하는 부분입니다. 다른 브라우저들까지 설명하기는 힘듭니다. 오페라는 크로미움(Chromium)쪽으로 움직이므로 크롬의 동작과 아주 비슷하게 될 것입니다. (물론, 만약 여러분이 클리어타입(ClearType)이 가능하도록 했다면!) 인터넥 익스플로러는 거의 모든 텍스트에 대해 서브픽셀 안티앨리어싱을 사용하는 것으로 보입니다만 윈도우즈 8의 메트로 모드에서는 그렇지 않은 것 같습니다. WebKit과 유사하게 동작하는 모듈을 블링크에게 제공한 사파리는 비록 더 많은 서브픽셀 안티앨리어싱을 제공하는 새로운 개선사항들은 없지만 크롬과 매우 유사하게 동작합니다. 파이어폭스는 인터넷 익스플로러처럼 거의 모든 텍스트에 서브픽셀 안티앨리어싱을 사용하는 동일한 방식으로 거의 동작합니다. 물론 완전히 같은 것은 아니며 서브픽셀 대신 그레이스케일 안티앨리어싱을 사용하는 모든 브라우저들의 경우처럼 될 개연성이 있습니다만 서브픽셀 안티앨리어싱이 브라우저들의 주요 세트들 간에 폭넓게 사용된다는 것을 아는 것은 좋은 일입니다.

결론

이제 여러분은 안티앨리어싱이 어떻게 동작하는지와 오늘날의 사이트들과 어플리케이션들에서, 특히 낮은 DPI를 가지는 디바이스 상에서는 더더욱, 왜 텍스트 렌더링의 차이점이 발생하는지에 대해 약간 알게 되습니다. 만약 텍스트 렌더링에 대한 크롬의 구현을 따라가보는데 흥미가 있으시다면 다음의 버그들에 특별히 관심을 기울이시기 바랍니다

리소스와 참조문서:

Comments

0