게임 데이터 가이드

글꼴 렌더링 파이프라인, 폰트 폴백·캐시 설계, 국제화(i18n) 텍스트 처리

oneplay1 2025. 10. 11. 13:42
게임에서 텍스트는 정보 전달의 최전선에 있다. 하지만 언어권이 달라지고 해상도·주사율·UI 스케일이 변하면, 같은 문장도 가독성과 성능이 크게 달라진다. 이 글은 엔진과 운영체제, 폰트 자산 사이에서 텍스트가 화면에 나타나기까지의 흐름을 정리하고, 폰트 폴백과 글리프 캐시(아틀라스) 설계를 통해 프레임 타임 변동을 줄이는 방법을 제시한다. 또한 한글·중문·영문처럼 글자 수·조합 규칙이 다른 스크립트를 동시에 표시할 때 필요한 국제화(i18n) 처리 기준을 정리한다. 핵심은 세 가지다. 첫째, 렌더링 파이프라인을 모듈로 나눠 레이아웃·셰이핑·래스터 단계의 병목을 파악한다. 둘째, 폴백 체인을 짧고 예측 가능하게 설계하고 글리프 캐시의 적중률을 끌어올린다. 셋째, 줄바꿈·문자 폭 계산·복합 스크립트 셰이핑 규칙을 표준화해 언어별 UI 표기를 일관되게 유지한다. 결과적으로 텍스트는 더 선명해지고, 동일 프레임 예산 안에서 안정적으로 출력된다.

글꼴 렌더링 파이프라인

글꼴 렌더링 파이프라인은 입력 문자열이 화면 픽셀로 변환되는 과정을 단계별로 구분해 관리한다. 일반적으로 엔진은 텍스트 요청을 받으면 먼저 스타일(폰트 패밀리·가중치·크기·힌팅)을 해석하고, 그다음 줄바꿈 규칙과 폭 측정으로 레이아웃을 확정한다. 이어서 셰이핑 엔진이 문자를 글리프 시퀀스로 변환하고, 필요 시 합자·자소 결합·문자 폭 조정을 적용한다. 마지막으로 글리프 비트맵 혹은 SDF(서인 거리장)를 래스터화해 아틀라스 텍스처에 배치하고, UI 패널에 드로우 콜을 발행한다. 이 흐름에서 병목은 보통 두 지점에서 발생한다. 첫째, 대량 텍스트가 한 프레임에 등장할 때 레이아웃·셰이핑 비용이 급증한다. 둘째, 캐시에 없는 글리프가 연속으로 요청되면 아틀라스 재배치와 업로드로 GPU/CPU 동기화가 늘어난다. 병목을 줄이려면 파이프라인을 비동기로 분리해 메인 스레드의 드로우 경로와 레이아웃·셰이핑 경로를 독립적으로 처리하고, 프레임 경계 밖에서 캐시 미스에 대비한 선-래스터(pre-raster) 큐를 운용하는 편이 유리하다. 고해상도·고주사율 환경에서는 텍스트 스케일 변동이 잦아진다. 동일 폰트라도 100%와 125% UI 스케일에서 필요한 글리프의 샘플링 방식이 달라지므로, 정해진 스냅 배율(예: 1.0/1.25/1.5)을 미리 정하고 각 배율용 아틀라스를 따로 운영하면 스케일 변경 시 재래스터 비용을 통제할 수 있다. 또한 SDF 기반 표기 방식을 사용하면 크기 변화에 좀 더 탄력적으로 대응할 수 있으나, 작은 크기에서 경계가 번지는 문제를 방지하기 위해 두께 보정과 감마 보정을 함께 적용해야 한다.

폰트 폴백·캐시 설계

폰트 폴백은 기본 폰트가 특정 코드 포인트(문자)를 제공하지 못할 때 대체 폰트에서 해당 글리프를 가져오는 절차다. 다국어 UI에서는 필수지만, 체인이 길수록 탐색과 로딩 비용이 커진다. 효율적 설계의 핵심은 세 가지다. 첫째, 폴백 순서를 언어권별로 짧게 유지한다. 한글 UI 기본: 본문용 고정폭/가변폭 1종 + 기호/이모지 전용 1종 + 희귀 문자 보조 1종 정도가 적절하다. 둘째, 런타임에서 폰트 파일을 통째로 메모리에 올리기보다, 사용 범위에 맞춘 서브셋(필요한 글리프만 추출) 자산을 번들링한다. 메뉴·버튼·알림 등 고빈도 UI 문자열은 사전에 빈도 상위 글리프를 추출해 서브셋 폰트로 묶어두면 초기 로딩과 캐시 적중률이 모두 개선된다. 셋째, 글리프 캐시는 “적중률·파편화·갱신 비용”을 균형 있게 관리한다. 아틀라스는 보통 여러 타일로 나누어 글리프 비트맵을 배치하는데, 동적 배치가 잦으면 빈 공간이 늘어 파편화가 심해진다. 이를 막기 위해 고정 라인 높이(예: 32px·48px·64px)를 가진 레인 기반 아틀라스를 사용하고, 각 레인에 배치될 글리프의 크기를 제한한다. 특정 언어권 이벤트(예: 일본어 시즌 문구)가 예고되면, 해당 코드 포인트 블록을 사전-래스터해 따로 보온 캐시에 보관했다가 첫 진입 프레임에 교체하는 전략이 안정적이다. 이모지·기호 폰트는 컬러 레이어를 포함해 래스터 비용이 높은 편이다. 글자 크기가 작을 때는 컬러 레이어를 단순화한 모노 레이어 폰트를 우선 사용하고, 확대/상세 화면에서만 컬러 레이어를 교체하면 프레임 타임 급증을 피할 수 있다. 최적화의 마지막 축은 드로우 콜 묶음이다. 같은 아틀라스·같은 블렌딩 상태·같은 셰이더를 공유하는 텍스트 뭉치를 하나의 배치로 묶고, UI 레이아웃이 비슷한 화면은 콘텐츠만 바뀌더라도 배치 순서를 고정해 상태 전환을 최소화한다. 이렇게 하면 텍스트가 많은 화면에서도 GPU 바인딩 비용이 눈에 띄게 줄어든다.

국제화(i18n) 텍스트 처리

국제화 텍스트 처리는 서로 다른 스크립트가 동시에 표시될 때도 균일한 가독성과 레이아웃 안정성을 확보하는 작업이다. 첫 단계는 줄바꿈 규칙이다. 한글은 어절 경계가 비교적 명확하지만, 영어는 하이픈 연결·단어 분할 규칙, 중국어는 금칙 문자(행두·행말) 규정을 고려해야 한다. 줄바꿈 알고리즘은 폭 측정과 함께 작동하므로, 언어별 규칙 테이블을 분리해 유지하는 편이 관리에 유리하다. 두 번째는 문자 폭과 커닝이다. 동일 본문이라도 한글·영문 혼용 시 폭 비율이 달라 헤딩이 흔들리기 쉽다. 헤딩·버튼 텍스트처럼 UI의 기준점이 되는 컴포넌트는 고정 폭 그리드 또는 탭 스톱을 두어 혼용 시에도 정렬이 흐트러지지 않게 한다. 세 번째는 셰이핑 규칙이다. 아랍어·인도계 문자처럼 조형이 문맥에 따라 변하는 스크립트는 반드시 컨텍스트 셰이핑을 거쳐야 하며, 이 단계가 비활성화되면 가독성 문제가 즉시 발생한다. 혼용 UI에서 언어 전환(예: 시스템 메시지 영문, 사용자 닉네임 한글·일문)은 폴백이 잦다. 이때 문장 단위로 언어 스팬(span)을 명시해 폴백 탐색을 줄이고, 동일 스팬 안에서만 폰트 교체가 일어나도록 제한하면 레이아웃 재계산이 안정화된다. 마지막으로 가독성 보정이다. 높은 DPI에서 텍스트는 선명하지만, 낮은 DPI·저휘도 패널·VA 패널 등 환경에서는 경계가 번져 보일 수 있다. 이 경우 힌팅과 감마를 UI 테마별로 분리해 명암비가 낮은 배경에서는 스트로크(외곽선) 대신 살짝 높은 내부 대비(예: 밝기 곡선 보정)를 적용한다. 색각 보정 모드가 켜질 때는 링크·강조 텍스트가 색상만으로 구분되지 않게 밑줄·아이콘 보조 표기를 함께 둔다. 결과적으로 국제화 처리의 목표는 “어떤 조합의 문자열이 들어와도, 같은 규칙으로 정확히 보인다”는 예측 가능성이다. 파이프라인·폴백·캐시·셰이핑·줄바꿈의 규칙을 분리해 표준화하고, 배포 전 지역별 샘플 팩으로 스트레스 테스트를 거치면 런칭 이후에도 안정적으로 확장할 수 있다.

텍스트 렌더링 파이프라인 레이아웃 셰이핑 래스터 드로우 배치
레이아웃→셰이핑→래스터→배치 단계
폴백 체인 기본 본문 이모지 보조 폰트 아틀라스 레인 레인 32px 레인 48px 레인 64px
짧은 폴백 체인과 레인 기반 아틀라스로 파편화 최소화
캐시 적중률과 드로우 콜 관계 70% 80% 85% 90%
캐시 적중률이 높을수록 드로우 콜은 줄어들어 성능이 안정화됨