1P by GN⁺ | ★ favorite | 댓글 1개
  • 기존 Multi-Channel SDF 방식은 얇은 획, 큰 아틀라스, 축소·확대, 부드러운 이동에서 한계가 남아 GPU 런타임 래스터화로 다시 구현함
  • 새 파이프라인은 현재 보이는 글리프의 Bézier 곡선 데이터만 GPU로 보내고, 런타임에 아틀라스에 그린 뒤 화면에서 샘플링함
  • 글리프가 화면에 남아 있으면 아틀라스 캐시를 유지하면서 샘플을 누적해 품질을 높이고, 첫 프레임 8 samples-per-pixel에서 시작해 최대 512 samples까지 정제함
  • 캐시 키에는 font, glyph_index, 픽셀 크기와 서브픽셀 오프셋이 포함되며, 8비트 고정소수점으로 가까운 위치와 크기를 같은 값으로 접어 재사용성을 높임
  • 모니터별 RGB 서브픽셀 구조를 샘플 영역으로 모델링하면 OLED G9 같은 비표준 배열에서도 색 번짐을 줄일 수 있고, 4K 전체 화면 텍스트 데모는 Radeon 9070 기준 약 0.1ms 피크 비용을 보임

SDF 대신 런타임 벡터 래스터화를 택한 이유

  • 기존 구현은 Multi-Channel Signed Distance Fields를 사용했고 대체로 잘 동작했지만, 실제 사용에서는 몇 가지 제약이 남아 있었음
    • 품질: 얇은 획이나 세부가 많은 폰트에서 특징이 사라지거나 아티팩트가 생겼고, 더 높은 해상도의 SDF가 필요해지는 경우가 있었음
    • 아틀라스 크기: SDF는 오프라인 생성 후 아틀라스에 저장되므로, 글리프가 많은 일본어·중국어 폰트는 단일 아틀라스로 굽기 어려움
    • 유연성: 축소·확대 문제나 서브픽셀 안티앨리어싱 같은 새 아이디어를 적용하기 까다롭고, 런타임 생성·편집 가능한 벡터 이미지에도 맞지 않았음
    • 단순성: 원본 글리프 곡선을 중간 텍스처로 바꾸는 단계가 시스템 복잡도를 늘림
  • Miama 같은 라틴 폰트도 글리프마다 64×64 영역을 쓰는 4096×1152 아틀라스가 필요했고, 여러 폰트를 런타임에 쓰면 메모리와 스트리밍 대역폭 비용이 커짐
  • 새 접근의 목표는 글리프 제작자가 만든 Bézier 곡선을 더 직접적으로 사용해 원본 데이터에서 최종 픽셀까지의 변환 단계를 줄이는 것임

전체 파이프라인

  • 핵심은 오프라인에 모든 글리프를 미리 굽는 대신, 현재 보이는 글리프의 곡선만 GPU로 보내 필요한 순간에 래스터화하는 방식임
  • 처리 흐름은 단순함
    • 폰트에서 글리프 곡선 데이터를 로드함
    • GPU가 런타임에 글리프를 아틀라스에 래스터화함
    • 화면 출력 시 해당 아틀라스를 샘플링함
  • 같은 글리프가 이후 프레임에서도 계속 쓰이면 아틀라스에 남겨두고 샘플을 누적해 고품질 서브픽셀 안티앨리어싱까지 정제함
  • 벡터 표현을 직접 렌더링하므로 해상도 변화에 대응하기 쉽고, 픽셀 전체 커버리지뿐 아니라 각 서브픽셀 요소의 커버리지까지 계산할 수 있음

글리프 곡선 처리

  • 폰트 로딩에는 FreeType을 오프라인 도구의 중간 계층으로 사용해 지원 포맷을 읽고, 각 글리프의 곡선을 순회해 자체 애셋 포맷으로 저장함
  • 글리프 곡선은 , 2차 Bézier, 3차 Bézier를 포함할 수 있으며, 셰이더를 단순하게 만들기 위해 모두 2차 Bézier로 변환함
    • 선은 두 점의 중간에 제어점을 하나 추가해 2차 Bézier로 만듦
    • 3차 Bézier는 두 개의 2차 Bézier로 나누며, 이는 차수를 낮추는 손실 변환임
  • 3차 Bézier를 두 개의 2차 Bézier로 나누는 방식은 시도한 폰트 대부분에서 잘 동작했지만, 오차를 더 줄이는 더 정교한 방법도 가능함
  • 더 높은 품질의 변환이 필요하면 오프라인 도구로 TrueType .ttf처럼 2차 Bézier만 가진 형식으로 바꿔 이 변환 자체를 피할 수 있음
  • Desmos 그래프에서 입력 3차 Bézier와 결과 2차 Bézier 두 개의 형태를 비교할 수 있음

커버리지 계산과 곡선 접근 최적화

  • 커버리지는 픽셀 단위로 수평 광선을 왼쪽에서 오른쪽으로 쏘고, 곡선과의 교차를 검사해 winding number를 누적하는 방식으로 계산함
  • 수학적 배경과 구현은 GreenLightning의 GPU Font RenderingSebastian Lague의 Rendering Text 영상을 참고할 수 있음
  • 교차 계산의 부정확성은 특정 높이의 샘플에서 발생할 수 있지만, 수백 개 샘플을 누적하면 한두 개 오차는 평균 후 거의 보이지 않음
    • 최대 512개 샘플을 누적할 때 한 샘플이 틀리면 0 대신 1/512=0.00195, 또는 1 대신 511/512=0.99804가 됨
    • 커버리지가 극단값에 가까울 때 클램프하는 임계값을 둘 수도 있음
  • 샘플 위치 분포에는 Martin Roberts의 $R_2$ sequence를 사용하고, Shadertoy 예제에서 시간에 따른 분포를 확인할 수 있음
  • 곡선 접근 비용을 줄이기 위해 글리프를 여러 수평 밴드로 나누고, 각 밴드에 닿는 곡선만 비트셋으로 저장함
    • 수평 광선만 추적하므로 각 텍셀이 검사할 곡선 집합을 크게 줄일 수 있음
    • wave 단위로 같은 밴드 범위를 접근하게 하면 곡선 반복과 읽기를 스칼라화할 수 있음
    • compute 셰이더에서 아틀라스에 래스터화할 때 스레드를 row-major로 수평 패킹해 wave가 닿는 밴드 범위를 최소화함

아틀라스 패킹과 캐시 키

  • 처음에는 화면에 직접 래스터화했지만, 매 프레임 고품질 안티앨리어싱을 계산하는 비용이 컸음
  • 대부분의 텍스트는 여러 프레임 동안 같은 크기와 위치로 남아 있고, 같은 글리프가 같은 크기로 반복되므로 아틀라스와 시간 누적이 적합함
  • 아틀라스는 필요한 글리프가 없으면 공간을 할당해 래스터화를 시작하고, 이미 있으면 기존 결과를 그대로 사용함
    • 프레임 중 아틀라스의 글리프를 검사해 계속 유지할지, 더 샘플링할지, 사용하지 않아 공간을 해제할지 결정함
  • 아틀라스 키는 다음 요소를 포함함
    • font
    • glyph_index
    • quantized_size_in_pixels_x, quantized_size_in_pixels_y
    • quantized_subpixel_offset_x, quantized_subpixel_offset_y
  • 서브픽셀 오프셋frac(pixel_position)에 해당하며, 글리프가 픽셀 그리드에 정확히 맞지 않거나 부드럽게 스크롤될 때 위치에 맞는 안티앨리어싱 결과를 만드는 데 필요함
  • 부동소수점 값을 그대로 키로 쓰면 수학적으로 같아야 할 값도 비트 단위로 달라질 수 있어, 8비트 소수부 고정소수점으로 가까운 위치와 크기를 같은 값으로 접음
  • 정적 텍스트가 많은 텍스트 에디터에서 고정폭 폰트를 쓴다면 문자 간격과 줄 위치를 픽셀 경계에 맞춰 같은 글리프의 아틀라스 캐시 적중률을 높일 수 있음

Z-Order 기반 아틀라스 배치

  • 런타임 글리프 배치는 Z-Order Packing과 자유 셀 비트셋을 사용함
  • Morton code 기반 Z-Order는 2D 셀을 긴 1D 배열처럼 다루게 해주며, 2의 거듭제곱 개수만큼 연속 셀을 할당하면 2D 아틀라스에서 정사각 영역이 됨
  • 기본 셀은 16×16 texel이고, 글리프 크기는 다음 2의 거듭제곱으로 올림됨
    • 예를 들어 25×29 글리프는 32×32 청크를 할당함
    • 이 경우 16×16 셀 4개가 필요하므로 정렬된 연속 4비트를 찾아 사용함
  • 라틴 알파벳의 길고 얇은 글리프는 세로형이 많아, 전치된 Z-Order를 쓰면 l, j, i, 1 같은 글리프가 절반 공간만 사용할 수 있음
  • 반대로 아랍어처럼 길고 얇은 글리프가 가로형인 경우에는 표준 Z-Order가 더 적합함

시간 누적으로 품질을 높이는 방식

  • 글리프가 아틀라스에 남아 있으면 매 프레임 샘플을 조금씩 더해 결과를 정제할 수 있음
  • 기본 스케줄은 글리프가 처음 나타난 프레임에 8 samples-per-pixel, 다음 프레임에 4, 그 다음 2, 이후 매 프레임 1개씩 추가해 총 512개까지 누적함
  • 첫 프레임 품질을 높게 잡는 이유는 부드럽게 이동하거나 크기가 바뀌는 글리프가 매 프레임 새로 초기화되는 것과 같기 때문임
  • 품질과 성능은 여러 방식으로 조절 가능함
    • 매 프레임 추가할 샘플·광선 수
    • 글리프 초기 몇 프레임의 샘플 증가 여부
    • 프레임당 총 샘플 수 상한
    • 기존 글리프를 매 프레임이 아니라 몇 프레임마다 갱신하는 time-slicing
    • 글리프 곡선 수에 따라 교차 검사 비용을 제한하는 방식
  • 이 구현에서 성능은 큰 문제가 되지 않았고, 도입부 전체 화면 텍스트는 Radeon 9070에서 4K 기준 약 0.1ms 피크를 보였으며, 글리프가 최대 샘플 수에 도달하면 비용은 빠르게 0에 가까워짐

서브픽셀 안티앨리어싱과 색 번짐

  • 서브픽셀 안티앨리어싱은 모니터 픽셀 안의 빨강·초록·파랑 요소를 각각 샘플 영역으로 보고 렌더링함
  • 전통적인 RGB LCD의 세로 줄무늬 구조에서는 수평 해상도가 사실상 3배가 되어, 4K 기준 3840×21603840×6480처럼 다룰 수 있음
  • OLED G9 같은 모니터는 표준 RGB 세로 줄무늬와 다른 비표준 서브픽셀 구조를 가진다는 점이 문제임
    • 기본 RGB 세로 직사각형 구조로 가정하면 위쪽에 초록, 아래쪽에 마젠타 색 번짐이 보임
    • 모니터의 실제 서브픽셀 구조에 맞춰 샘플 위치를 설정하면 색 번짐이 거의 없고 부드러운 결과가 나옴
  • Subpixel Zoo는 다양한 서브픽셀 구조 사례를 보여주며, LG WOLED의 red-white-blue-green 구조는 표준 순서와 다른 예임
  • 서브픽셀 요소를 실제 물리 크기보다 크게 보고 서로 겹치게 설정하면 더 정확한 결과가 나왔음
    • 서브픽셀의 빛은 자연스럽게 섞이고 약간 확산되므로, 샘플 영역이 물리적 서브픽셀보다 큰 것처럼 동작함
    • 샘플 영역은 픽셀 밖으로도 번져야 하며, 주변 픽셀의 서브픽셀 빛과도 섞임
  • Evan Wallace의 Easy Scalable Text Rendering은 서브픽셀 안티앨리어싱 후 수평 블러가 필요하다고 보며, 이는 서브픽셀 요소를 더 크고 겹치게 보는 방식과 사실상 같은 효과임

디스플레이 서브픽셀 정보를 소프트웨어가 알 수 있어야 함

  • 모니터의 임의 서브픽셀 구조에 접근할 수 있다면, 일반적인 서브픽셀 안티앨리어싱과 텍스트 렌더링 품질을 개선할 수 있음
  • 공통 디스플레이 프로토콜을 통해 이런 정보가 제공되면 표준 배열 모니터에서도 하드웨어별로 더 세밀한 렌더링이 가능함
  • 디스플레이 제조사는 텍스트 렌더링 문제 때문에 더 나은 서브픽셀 구조 실험을 피하지 않아도 됨
  • Samsung은 QD-OLED에서 G8에서 G9로 가며 이런 문제를 줄이기 위해 서브픽셀 구조를 바꿨고, LG WOLED와 Samsung QD-OLED에서는 색 번짐이 흔히 지적됨
  • 이 문제는 하드웨어 교체보다 소프트웨어 보정으로 다룰 여지가 있음

실시간 글리프 렌더링의 실용적 가치

  • 좋은 UI와 텍스트 품질은 제품의 체감 품질을 끌어올릴 수 있음
  • 게임에서는 텍스트 박스, 메뉴, 제목, 알림처럼 사용자의 시선이 모이는 요소가 자주 등장하며, 텍스트 품질 저하는 렌더링이 나쁜 3D 장면만큼 경험에 영향을 줄 수 있음
  • Persona 시리즈, Metaphor: ReFantazio, Nier: Automata는 UI와 텍스트 표현의 좋은 사례임
  • 실시간 글리프 렌더링 품질을 개선하려는 시도는 UI와 게임 렌더링 모두에서 실질적인 가치가 있음

댓글과 토론

Hacker News 의견들
  • 첫 영상에서 기울임꼴 j의 점은 어떻게 된 건가요?

  • 서브픽셀 글꼴 렌더링은 가독성에 중요하지만, 글에서 짚듯 기존 디스플레이 표준에서 픽셀 배치 사양을 얻을 수 없다는 게 아쉬움

    • 표준 해상도 디스플레이에서나 해당되고, 그때도 “필수”라기보다는 있으면 좋은 정도임
      세상은 점점 Retina급 디스플레이로 옮겨갔고, 거기서는 서브픽셀 렌더링의 이유가 거의 없음
      스크린샷이 특정 서브픽셀 배치에 묶이고, 비트맵 확대/축소도 어렵다는 골칫거리가 많음
      CRT와 Retina 사이 LCD 시대의 일시적 혁신이었고, 지금은 뒤를 보는 기술에 가까움. Apple이 몇 년 전 macOS에서 제거한 데는 그럴 만한 이유가 있음
    • DisplayID 표준, 즉 EDID의 현대적 후속 표준은 https://en.wikipedia.org/wiki/DisplayID#0x0C_Display_device_...에 따르면 적어도 이를 허용하려는 의도가 있어 보임
      디스플레이 제조사가 구현하지 않는 건지 궁금함. 어쨌든 가장 흔한 디스플레이 모델에 대해서는 하드웨어 정보 데이터베이스에 쉽게 추론해 저장할 수 있는 정보임
    • 왜 아직도 안 되는지 모르겠음. 수십 년 전부터 가능했던 일 아닌가 싶음
      글은 훌륭하고, 다양한 사례를 보여주는 “subpixel zoo”도 링크함: https://geometrian.com/resources/subpixelzoo/
    • “비극”은 좀 과장임. 각 운영체제가 예전 Windows의 ClearType 튜너에 해당하는 기능을 제공하고, 결과를 화면이나 모니터 모델별로 기억하면 됨
      모니터가 잘못된 배치를 보고하는 피할 수 없는 경우에도 이런 방식이 필요함
    • 서브픽셀 렌더링은 대부분의 언어에서는 필요하지 않음
      안티앨리어싱 없는 비트맵 글꼴이나 힌팅된 벡터 글꼴만으로도 가독성이 매우 좋음
      중국어나 일본어처럼 문자가 아주 복잡한 세부를 가진 언어에서만 중요해짐
  • GTK4는 렌더링을 GPU로 옮기면서 RGB 서브픽셀 렌더링을 포기했음
    GPU 중심 결정 때문에 RGB 서브픽셀 렌더링을 계속하기 어렵게 됐다고 들었는데, 글은 가능하다는 걸 보여줌
    그렇다면 GTK의 이유는 다른 데 있었거나, 제시된 해법에 단점이 있거나, 기존 스택에 잘 통합되지 않는 것일 수 있음

    • Cosmic Text(Cosmic DE)는 swash를 통해 GPU에서 이걸 할 수도 있음. 서브픽셀 렌더링을 지원함
  • WebGL / WebGPU에서 SDF와 MSDF를 구현하는 방법에 관심 있다면, 직접 쓴 튜토리얼을 보면 됨: https://infinitecanvas.cc/guide/lesson-015#msdf

    • 좋아 보임. Rust의 WebGPU 구현인 WGPU에 관심이 있는데, 이 튜토리얼은 스스로 그렇게 홍보하지는 않지만 사실상 고급 과정처럼 보임
      JavaScript 예제를 Rust로 옮겨 본 적이 있는데, 그냥 복사/붙여넣기를 할 수 없고 API는 충분히 비슷해서 포팅하기 쉬워 학습에 이상적임
      WGPU 문서를 익숙하게 쓰게 되는 계기도 됨
    • 사이트 형식이 정말 좋음
      GPU 관련 튜토리얼을 만드는 걸 좋아해서 이런 식으로 구성하고 싶은데, 기존 템플릿인지 어떤 강의의 일부인지 궁금함
  • Slug 라이브러리는 이런 GPU 글리프 래스터라이저를 구현한 상용 미들웨어임
    [1]: https://sluglibrary.com/

    • 웹사이트에서 알고리즘을 꽤 많이 직접 설명하던데, 특허가 있는지 궁금함
      cosmic-text의 글꼴 파싱과 레이아웃 일부를 써서 오픈소스 wgpu 버전을 만들면 재미있겠지만, 끝에 가서 Slug에게 소송당한다면 전혀 재미없을 것임
  • GPU가 사실상 무한한 정점/픽셀 그리기 능력을 가진 것처럼 보이는데, 왜 텍스트를 오프라인으로 렌더링해 아틀라스에 저장하고 SDF 같은 트릭까지 써야 하는지 아직 이해가 안 됨
    글에서도 글리프 곡선을 아틀라스에 쓴다고 하는데, 셰이더가 텍스트를 직접 렌더링하면 안 되는 이유가 궁금함
    베지어를 삼각형 메시로 변환하는 방법은 분명 있을 것 같음. CAD 앱용 GPU 텍스트 렌더러를 막 시작하려는 참이라 곧 이유를 알게 되길 바람

    • 같은 글리프를 반복해서 렌더링할 때는 결과를 캐시하는 편이 대부분 더 저렴함
      GPU는 빠르지만 무한히 빠르지는 않고, 미리 렌더링된 텍스처를 샘플링하는 데 매우 강함
      속도만의 문제가 아니라 전력 소모 문제이기도 함. 이미 모니터 주사율에 도달했다면 추가 성능 향상은 반응성을 높이지 못하지만 배터리 지속 시간은 늘어날 수 있음
      렌더링에는 “충분히 빠름”이라는 게 없고, 더 빨라지면 항상 이득이 있음
    • 기본적인 글꼴조차 일반적인 표시 크기에서 삼각형 밀도가 엄청나게 높음
      현대 GPU 아키텍처는 모두 고밀도 기하 처리를 잘 못함. 이런 경우에는 삼각형을 GPU에 그냥 밀어 넣는 방식이 아틀라스나 다른 기법보다 매우 비효율적임
      대부분의 GPU는 픽셀 셰이더를 4개 단위로 디스패치함. 삼각형이 모두 1픽셀 크기라면 셰이더 스레드 3개는 시각적 출력에 기여하지 못하게 됨
      이를 쿼드 오버드로라고 부름. 게다가 실제 이유 없이 정점 처리에도 많은 시간을 씀
    • GPU에는 무한한 정점/픽셀 그리기 능력이 없음. 텍스트를 직접 렌더링하는 건 단순히 더 비쌈
      가능은 하지만, 별 이득 없이 프레임 예산 일부를 포기하고 전력 사용량을 늘리게 됨
    • 삼각형은 잘못된 선택이지만, 큰 방향은 맞는 문제 제기임
      글쓴이는 픽셀당 최대 512샘플로 베지어 곡선을 슈퍼샘플링하기 때문에 아틀라스를 쓰는데, 이는 매우 비쌈
      대신 베지어 곡선 영역과 서브픽셀 영역의 교차 적분을 계산하는 식이면 훨씬 빠를 수 있고, 아틀라스 없이 실시간으로 돌면서 슈퍼샘플링보다 더 정확할 것 같음
    • GPU는 매우 빠르지만 무한하지는 않음. GPU 시간을 텍스트에 쓰면 다른 데 쓸 수 없음
      그리고 거의 항상 그 시간을 다른 데 쓰고 싶어짐
      더 많은 GPU 시간이 필요할수록 최소 요구 하드웨어도 더 빨라져야 함. 텍스트는 멋지고 중요하지만, 사용자나 고객을 잃을 만큼 중요하지는 않을 수 있음
  • “새 OLED들은 보기엔 좋지만 비표준 서브픽셀 구조 때문에 색 번짐 문제가 있다”는 정도보다 더 나빠 보임
    이해한 바로는 단순히 비표준이 아니라, OLED에는 서로 호환되지 않는 여러 서브픽셀 배치가 있음
    그래서 FreeType이 OLED용 서브픽셀 렌더링을 구현하지 않았고, 텍스트 작업이 필요하면 OLED를 피해야 하는 이유가 됨
    FreeType만의 문제도 아니고 Qt, GTK 같은 GUI 툴킷도 함께 맞춰야 함. 해결 진전이 있는지는 잘 모르겠음
    임의의 모니터 서브픽셀 구조에 접근할 수 있으면 좋겠고, 이런 정보는 EDID로 전달되어야 할지도 모름

    • 어느 정도 표준적인 서브픽셀 배치를 가진 OLED도 있음
      예를 들어 내 노트북은 세로 방향 BGR 배치인데, FreeType과 KDE가 잘 지원함
      이상한 배치는 HDR 디스플레이에서 특정 색, 특히 파란색이 너무 빨리 타버리지 않게 색마다 다른 크기를 써야 해서 생기는 경우가 많은 것 같음
    • 이론적으로는 맞지만, 실제로는 4K OLED 디스플레이에서 코드를 쓰고 있는데 어떤 아티팩트도 느끼지 못했음
  • 매우 인상적인 작업임
    이 분야에 익숙하지 않은 사람들을 위해 덧붙이면, Valve가 게임용 SDF 텍스트 렌더링을 만들었고 2007년에 이 주제의 획기적인 논문을 발표했음
    지금도 비디오 게임에서 거의 변형 없이 매우 널리 쓰이는 기법임
    2012년 Behdad Esfahbod는 OpenGL ES로 GPU에서 동작하는 SDF 구현인 Glyphy를 만들었고, 성능과 빠른 텍스트 변환 같은 새 기능 때문에 널리 인정받았지만 폭넓게 쓰이진 않았음
    현대 운영체제와 웹 브라우저는 이런 기법 대신 1990년대식 TrueType 래스터화에 의존하는 쪽을 선호함
    가볍고 효과적인 접근이지만, 글에서 보이듯 서브픽셀 정렬이나 임의 서브픽셀 배치를 할 수 없고, 확대/축소는 성능 비용이 크며, 기울이기·회전·3D 변환 같은 복잡한 변환도 텍스트 렌더링 엔진 안에서 할 수 없음
    회전되거나 변형된 텍스트가 필요하면 비트맵을 재샘플링해야 하는데, 가독성을 만드는 작은 특징들을 모두 망가뜨려 보기 좋지 않음
    발전이 더딘 이유는 이득에 비해 작업량과 위험이 너무 크기 때문일 수 있음. 현대 웹 브라우저 엔진을 GPU 가속 텍스트 렌더링으로 다시 쓴다고 상상하면 만만치 않음
    글리프 렌더링은 한 부분일 뿐이고 줄바꿈 처리는 또 다른 문제임. CPU와 GPU 사이 통신이 많이 필요해 느릴 수 있고, 소프트웨어와 GPU의 깊은 통합도 어려움

    • 텍스트 셰이핑과 레이아웃, 줄바꿈까지 포함한 부분은 렌더링과 거의 완전히 별개인데 왜 그렇게 말하는지 잘 모르겠음
    • https://github.com/servo/pathfinder는 GPU 컴퓨트 셰이더로 이 작업을 수행함
      이 방식은 SDF처럼 하드웨어 3D 렌더링 파이프라인에 억지로 맞추는 것보다 성능이 훨씬 좋음
    • 기록 차원에서 말하면, 서브픽셀 안티앨리어싱을 포함한 텍스트 렌더링은 Windows에서 오래전부터 GPU 가속되었고 Chrome/Firefox에서도 오래전부터 GPU 가속됐음
      Safari도 아마 그럴 것 같지만 직접 확인해 말할 수는 없음
      최신 기술 수준이나 사용자에게 배포되는 구현이 발전하지 않았다는 생각은 틀렸음
    • SDF는 만능이 아님
      SDF는 주어진 픽셀에서 글자 가장자리까지의 국소 거리(Distance)를 데이터의 2차원 배열인 장(Field)로 인코딩하고, 그 거리가 글자 내부인지 외부인지를 부호(Sign) 비트로 표시함
      각 글자는 작은 데이터 맵을 가지며, GPU 친화적인 이미지 파일 형태로 함께 패킹되고, 각 글자의 부분 이미지를 어디서 찾을지 알려주는 설명 파일과 함께 SDF 렌더링 셰이더가 사용함
      이런 글자 정의는 필드 값 사이의 선형 보간에 매우 강해서, 비교적 낮은 해상도의 맵으로도 거의 완벽한 확대가 가능함. GPU도 맵의 픽셀 값을 보간하는 데 능함
      하지만 중요한 건 이 맵들을 개발 중 기존 글꼴 시스템에서 렌더링하려는 모든 문자에 대해 미리 처리해야 한다는 점임. 글꼴이 지원하는 모든 문자마다 필요함
      고해상도 비트맵 글꼴로 모든 문자를 렌더링하는 것보다는 데이터가 훨씬 적지만, 글꼴 윤곽 정의 자체보다는 훨씬 많음
      운영체제나 브라우저처럼 전 세계의 가능한 모든 텍스트를 지원하려는 시스템은 SDF를 텍스트 렌더링 시스템으로 쓸 수 없음. 전체 유니코드 문자 집합에 대한 SDF 맵이 필요해져 너무 커짐
      게임은 대체로 지역화가 충분히 잘 안 되어도 되거나 완전히 임의의 텍스트를 표시하지 않아도 되기 때문에 잘 맞음
      원래 SDF는 이모지도 지원할 수 없음. 글리프 가장자리까지의 거리만 인코딩하고 글리프 내부 색상 정보는 담지 않기 때문임
      여러 색상을 지원하는 개선판인 Multichannel SDF가 있긴 하지만, 전체 색상 수에는 제한이 있음
      실제로 게임 내 텍스트에 SDF를 쓰면서 전 세계 커뮤니티가 상호작용하는 채팅 시스템도 있는 게임을 자세히 보면, 게임 내 텍스트와 채팅 시스템의 텍스트 렌더링이 다를 가능성이 큼
    • 현대 웹 브라우저 엔진을 GPU 가속 텍스트 렌더링으로 다시 쓰는 건 까다롭지만, 이미 부분적으로는 하고 있다고 생각했음
      https://keithclark.co.uk/articles/gpu-text-rendering-in-webk... (2014)에 따르면 “현재 버전의 Chrome, Safari 또는 Opera에서 요소가 GPU로 승격되면 서브픽셀 안티앨리어싱을 잃고 텍스트가 그레이스케일 방식으로 렌더링된다”고 함
      그렇다면 빠진 게 무엇인지 궁금함. 그 문장대로라면 적어도 UTF-8 문자열에서 비트맵으로 가는 단계의 일부는 GPU에서 할 수 있는 것 아닌가 싶음
  • 인상적인 작업임
    하지만 서브픽셀 안티앨리어싱은 개인적으로 별 의미가 없다고 봄. 72dpi 모니터를 쓰던 2000년대에는 괜찮은 해킹이었지만, 현대 Retina 화면에서는 알아보기 어렵고 아주 작은 개선을 위해 여러 단점을 얻음
    불투명 배경 위에서만 동작하고, 래스터화된 결과에 크기 변경·미러링·블러 같은 효과를 적용할 수 없으며, 스크린샷을 다른 디스플레이에서 보면 나빠짐

    • 서브픽셀 안티앨리어싱을 없애면 크게 단순해지겠지만, 아직 많은 데스크톱 사용자가 저 DPI 모니터를 쓰고 있음
      Firefox 하드웨어 조사 [1]에 따르면 사용자 16%가 1366x768 해상도 디스플레이를 사용함
      단순한 구형 하드웨어만의 문제가 아니라, 96dpi 모니터와 노트북은 지금도 생산되고 있음
      [1]: https://data.firefox.com/dashboard/hardware
    • 결국 “나는 고 DPI 화면을 쓰니 그렇지 않은 사람은 신경 안 쓴다”는 말로 들림
      다른 논거들은 적용 가능한 곳에서 서브픽셀 렌더링이 주는 더 나은 결과에 비하면 별로 중요하지 않음
    • 글쓴이가 바라는 대로 디스플레이의 서브픽셀 배치를 알아내는 프로토콜이 생기고 널리 채택되더라도, 일부 제조사가 틀리게 구현해 최종 사용자가 이해하기 매우 어려운 렌더링 문제를 만들 가능성이 큼
  • SDF는 가장 가까운 가장자리까지의 픽셀 거리를 계산하지만, 전통적인 글꼴 렌더러는 픽셀 커버리지를 계산한다는 점이 중요함
    픽셀 커버리지가 최적임. 작은 글꼴에서는 가장자리가 만나는 부분에서 SDF가 나쁘게 보일 수 있음
    고 PPI 디스플레이에서는 덜 문제가 될지도 모르겠음. 직접 SDF 렌더러를 구현했는데 FreeType보다 나쁘게 보였음

    • 커버리지와 거리의 구분은 핵심이 아님. 거리장 렌더러에서도 커버리지는 아주 쉽게 계산할 수 있음
      다만 교차점, 또는 일반적으로 날카로운 모서리에서 거리장이 문제를 일으킨다는 지적은 맞음
      여러 거리장을 두고 그 교차를 렌더링하면 어느 정도 완화할 수 있음. 예를 들면 https://github.com/Chlumsky/msdfgen가 있음