TECH 으로 돌아가기
TECH HACKER NEWS 오늘 9분 읽기 31 READS

GPU로 글자를 그리는 세 가지 방법: SDF, MSDF, Slug는 뭐가 다를까?

GPU로 글자를 그리는 세 가지 방법: SDF, MSDF, Slug는 뭐가 다를까?
SOURCE IMAGE · HACKER NEWS
GPU로 글자를 그리는 세 가지 방법: SDF, MSDF, Slug는 뭐가 다를까?

글자 하나 그리는 게 왜 이렇게 어려울까요?

게임이나 3D 앱, 요즘 많이 쓰는 GPU 기반 UI 프레임워크를 만들다 보면 꼭 한 번은 부딪히는 문제가 있어요. 바로 텍스트 렌더링이에요. 웹 브라우저나 OS가 알아서 글자를 예쁘게 그려주니까 평소엔 신경 쓸 일이 없는데요, GPU로 직접 화면을 그리는 순간 얘기가 달라지거든요.

왜 그러냐면요, 폰트 파일 안에 있는 글자는 사실 곡선의 모음이에요. 'A'라는 글자는 픽셀 그림이 아니라 '여기서 여기까지 직선, 여기서부터는 이런 베지어 곡선' 같은 수학적인 윤곽선 정보로 저장되어 있어요. 반면에 GPU는 기본적으로 삼각형과 텍스처(이미지)를 그리는 데 특화된 장치고요. 그래서 '곡선으로 된 글자를 GPU가 잘하는 방식으로 어떻게 바꿔서 그릴까?'가 핵심 질문이 돼요.

가장 단순한 방법은 글자를 미리 비트맵 이미지로 구워서(아틀라스라고 불러요) 텍스처로 붙이는 거예요. 그런데 이러면 글자를 확대했을 때 뭉개지고, 3D 공간에서 비스듬히 보이거나 회전하면 금방 지저분해져요. 이 문제를 풀려고 나온 대표적인 기법이 SDF, MSDF, 그리고 Slug예요. 이번 글은 이 세 가지를 비교한 글을 바탕으로 각각의 원리와 장단점을 풀어볼게요.

SDF: '경계선까지 거리'를 저장하자

SDF(Signed Distance Field, 부호 있는 거리장)는 2007년 Valve가 팀 포트리스 2에서 쓰면서 널리 알려진 방법이에요. 이게 뭐냐면, 텍스처의 각 픽셀에 '이 점이 글자 윤곽선에서 얼마나 떨어져 있는지'를 저장하는 거예요. 글자 안쪽이면 양수, 바깥이면 음수 식으로요.

이렇게 해두면 셰이더에서 '거리가 0인 지점'을 기준으로 안과 밖을 나누기만 하면 돼요. 거리 값은 픽셀 사이에서 부드럽게 보간되니까, 작은 텍스처로도 꽤 크게 확대해서 깔끔한 윤곽을 얻을 수 있어요. 게다가 거리 정보가 있으니 외곽선, 그림자, 글로우 효과를 셰이더 몇 줄로 공짜처럼 만들 수 있다는 게 큰 장점이에요.

단점도 분명해요. 거리 값 하나만으로는 날카로운 모서리를 표현하지 못해요. 'M'이나 'V'처럼 뾰족한 꼭짓점이 있는 글자를 크게 확대하면 모서리가 동글동글하게 녹아버리거든요. 해상도를 올리면 나아지지만 그만큼 메모리를 더 쓰게 되고요.

MSDF: 채널 세 개로 모서리를 살리자

이 모서리 문제를 해결하려고 Viktor Chlumský가 만든 게 MSDF(Multi-channel SDF)예요. 아이디어가 꽤 영리한데요, 거리 정보를 하나가 아니라 R, G, B 세 채널에 나눠서 저장해요. 윤곽선의 각 구간(엣지)에 색을 배정하고, 채널마다 서로 다른 엣지 기준의 거리를 담는 거죠.

셰이더에서는 세 값의 중앙값(median)을 취해서 최종 거리를 구해요. 두 엣지가 만나는 모서리 근처에서는 채널들이 서로 다른 값을 가지니까, 중앙값을 쓰면 뾰족한 꼭짓점이 그대로 살아나요. 결과적으로 같은 텍스처 크기로 SDF보다 훨씬 선명한 글자를 얻을 수 있어요. 오픈소스 도구인 msdfgen, msdf-atlas-gen 덕분에 게임 엔진이나 WebGL 프로젝트에서 요즘 가장 흔히 쓰이는 방식이기도 해요.

하지만 MSDF도 결국 미리 구운 아틀라스라는 한계는 그대로예요. 아주 크게 확대하면 여전히 품질이 떨어지고, 엣지 색 배정이 꼬이면 이상한 아티팩트(깨진 점이나 선)가 생기기도 해요. 또 새로운 글자가 필요할 때마다 아틀라스를 생성해야 해서, 한글처럼 글자 수가 많은 언어에서는 관리가 꽤 번거로워요.

Slug: 아틀라스 없이 곡선을 직접 그리자

Slug는 Eric Lengyel이 만든 라이브러리로, 접근 방식이 완전히 달라요. 거리장을 미리 굽는 대신, 폰트의 베지어 곡선 데이터를 그대로 GPU에 올리고 픽셀 셰이더가 매 픽셀마다 '이 점이 글자 안에 있는가?'를 곡선으로부터 직접 계산해요.

쉽게 비유하면, SDF/MSDF가 '지도를 미리 인쇄해두고 확대해서 보는 것'이라면 Slug는 '매번 좌표를 보고 정확히 새로 그리는 것'이에요. 그래서 어떤 크기로 확대해도, 어떤 각도로 기울여도 수학적으로 정확한 윤곽이 나와요. 안티앨리어싱 품질도 뛰어나고, 아틀라스를 만들 필요도 없어요.

대가는 픽셀당 연산량이에요. 각 픽셀이 여러 곡선을 검사해야 하니까, Slug는 글자를 가로·세로 띠(밴드)로 나눠서 각 픽셀이 필요한 곡선만 보도록 최적화해요. 또 곡선과 픽셀 광선의 교차를 수치적으로 흔들리지 않게 판정하는 기법이 핵심 노하우고요. 참고로 Slug는 오랫동안 상용 라이선스 제품이었다는 점도 선택할 때 고려해야 해요.

업계 흐름에서 보면

세 방식은 결국 '미리 계산해둘 것이냐, 매번 계산할 것이냐'의 스펙트럼 위에 있어요. SDF는 가장 가볍고 효과 만들기 좋지만 품질 한계가 있고, MSDF는 그 균형을 크게 개선한 실용적인 선택이고, Slug는 품질 끝판왕이지만 GPU 비용이 더 들어요.

이 흐름은 텍스트에만 국한되지 않아요. Rive 같은 벡터 애니메이션 런타임이나 Vello 같은 GPU 벡터 렌더러도 '곡선을 GPU에서 직접, 정확하게 그리자'는 방향으로 가고 있거든요. GPU 성능이 계속 올라가면서, 예전엔 사치였던 '매 프레임 정확한 계산'이 점점 현실적인 선택지가 되고 있는 거죠.

한국 개발자에게 주는 시사점

게임 클라이언트나 WebGL/WebGPU 기반 서비스를 만든다면 이 선택은 꽤 실무적인 문제예요. 특히 한글은 조합 가능한 글자가 1만 1천 자가 넘기 때문에 아틀라스 방식은 메모리와 생성 시간 부담이 커요. 자주 쓰는 글자만 미리 굽고 나머지는 동적으로 생성하는 전략이 필요하죠. 반대로 Slug 계열처럼 곡선을 직접 그리는 방식은 글자 수에 덜 민감하다는 장점이 있어요.

간단한 HUD나 UI 텍스트라면 MSDF로 시작하는 게 가장 무난하고, 텍스트를 3D 공간에서 자유롭게 확대·회전해야 하는 경우(VR, 지도, CAD 등)라면 곡선 직접 렌더링 방식을 검토해볼 가치가 있어요. 셰이더 공부를 하는 분이라면 SDF 셰이더를 직접 짜보는 것만으로도 GPU 그래픽스의 감을 잡는 데 큰 도움이 될 거예요.

마무리

한 줄 정리: SDF는 가볍고, MSDF는 실용적이고, Slug는 정확하다. 정답은 여러분 프로젝트의 확대 배율과 글자 수에 달려 있어요.

여러분은 GPU 텍스트 렌더링에 어떤 방식을 쓰고 계신가요? 특히 한글 폰트를 아틀라스로 다룰 때 겪었던 문제나 나름의 해결책이 있다면 공유해주세요!


🔗 출처: Hacker News

SOURCE · HACKER NEWS
원문 전체 보기 → https://alphapixeldev.com/sdf-vs-msdf-vs-slug-vs-rive-gpu-te...
SHARE
NEXT · CHOOSE

변화를 읽었다면,
내가 만들 수익 구조를 고릅니다.

정보를 더 모으는 데서 멈추지 않고, 광고·외주·판매·중개·구독 중 내 상황에 맞는 출발점을 정해보세요.

21가지 수익 구조 살펴보기 →
처리 중...