GN⁺: 텍스처 없는 텍스트 렌더링 기술
(poniesandlight.co.uk)-
텍스처 없는 텍스트 렌더링
- 전통적으로 텍스트를 렌더링하려면 폰트의 모든 글리프를 아틀라스로 렌더링하고, 이를 텍스처로 바인딩한 후, 화면에 삼각형을 그려 글리프를 하나씩 렌더링해야 함.
- 디버그 메시지를 빠르게 출력하기 위한 간단한 방법을 소개함.
- 모든 텍스트를 단일 드로우 콜로 그릴 수 있는 기술을 설명함.
-
폰트: 텍스처 없는 픽셀
- 폰트 아틀라스 텍스처를 제거하기 위해, 프래그먼트 셰이더 내부에 폰트 아틀라스와 유사한 것을 저장해야 함.
- 정수 상수를 사용하여 비트맵을 저장할 수 있으며, 이를 통해 글리프를 렌더링할 수 있음.
- 8비트 정수를 비트맵으로 사용하여 GLSL 프래그먼트 셰이더에서 화면에 그릴 수 있음.
-
단일 드로우 콜
- 인스턴스 드로우 콜을 사용하여 반복적인 드로우 명령을 피할 수 있음.
- 각 인스턴스에 대해 위치 오프셋과 출력할 텍스트를 포함한 데이터를 사용함.
- 메시지를 4개의 문자로 나누어 uint32_t로 변환하여 word_data 구조체에 저장함.
-
버텍스 셰이더
- 버텍스 셰이더는 세 가지 출력을 생성함.
- gl_Position에 삼각형의 정점을 화면에 배치함.
- 출력할 단어를 프래그먼트 셰이더로 전달함.
- 텍스처 좌표를 생성하여 uv 좌표를 계산함.
-
프래그먼트 셰이더
- 프래그먼트 셰이더는 텍스트를 렌더링하기 위해 세 가지 정보를 필요로 함.
- uv 좌표를 글리프 비트맵의 올바른 비트에 매핑하여 글리프를 렌더링함.
- 비트가 설정된 경우 전경색으로, 설정되지 않은 경우 배경색으로 렌더링함.
-
전체 구현 및 소스 코드
- 이 기술의 구현은 le_print_debug_print_text 모듈의 소스 코드에서 찾을 수 있음.
- 이 모듈은 디버그 메시지를 화면에 쉽게 출력할 수 있도록 함.
Hacker News 의견
- ShaderToy에서 간단한 산술을 통해 코드를 작성하는 것이 재미있고 쉬운 작업임. 다양한 텍스트 해킹 예시가 많음
- 예: 300자 미만의 Matrix, 녹색 CRT 디스플레이 효과 등
- 이 방법은 창의적이지만 결과물이 아름답지는 않음. 더 나은 결과를 위해 더 많은 비트를 추가할 수 있지만, 효율적인 방법은 흑백 픽셀을 사용하여 텍스처로 저장하는 것임
- 현대 3D 렌더링 엔진에서 텍스트를 그리는 일반적인 방법은 SDF 텍스트를 사용하는 것임. 이는 전통적인 텍스처 아틀라스를 사용하여 서명 거리 필드의 아틀라스를 생성함
- 텍스트 렌더링 알고리즘을 직접 시도해본 적이 없지만 여러 가지를 구현한 경험이 있음. 해상도 독립성과 안티앨리어싱이 필요했기 때문에 이 방법은 도움이 되지 않았음
- 이 방법은 Will Dobbie의 방법과 개념적으로 유사하지만 더 간단함. 픽셀 데이터를 배열에 저장하는 방식임
- 텍스트를 메쉬로 렌더링하는 옵션도 있음. TextMeshPro는 서명 거리 필드를 사용하여 임의의 스케일을 처리함
- 전통적인 텍스처 방식과 성능 비교를 하면 재미있을 것임. 현대 GPU의 간단한 작업에서는 성능이 "예"라는 답변이 나올 가능성이 큼
- Sebastian Lague의 비디오에서 다양한 폰트 렌더링 기법을 다룸
- 폰트 데이터를 프래그먼트 셰이더 소스 코드에 포함시키는 유사한 기술을 사용한 경험이 있음.
snprintf
를 사용하여 GPU 버퍼에 직접 출력함 - 이 방법은 BBC Basic에서 작은 8x8 스프라이트를 그리는 것과 유사함. 35년 전의 추억을 떠올리게 함
- GPU는 텍스처에서 렌더링하는 데 효율적이지만 비트 조작에는 상대적으로 느림. 메모리를 절약하지만 실제로 아틀라스를 사용하는 것보다 빠른지는 의문임
- 작은 텍스처를 GPU에 업로드하는 것이 성능에 큰 영향을 미치는지에 대한 질문이 있음. 2D로 텍스처에 문자열을 렌더링하고 두 삼각형에 텍스처를 표시하는 것이 가능한지 궁금함