Quick Reference
Rasterization은 primitive를 화면의 coverage sample과 fragment 후보로 변환하는 단계입니다. fragment shader와 depth/stencil/blend 비용은 화면을 덮는 면적과 overdraw에 따라 늘어나므로, 정점이 세 개인 fullscreen triangle도 해상도만큼의 fragment 작업을 만들 수 있습니다.
| 단위 | 바로 하는 일 | 픽셀과의 관계 |
|---|---|---|
| Primitive setup | clip된 삼각형의 screen-space edge와 범위를 준비 | 픽셀보다 앞 단계 |
| Coverage sample | sample 위치가 삼각형 내부인지 검사 | MSAA에서는 한 픽셀에 여러 개 |
| Fragment | 보간된 입력으로 shader가 계산할 후보 | depth/stencil/blend 전이라 최종 픽셀이 아님 |
| Pixel / attachment | 테스트와 blend를 통과한 결과가 저장되는 위치 | 같은 픽셀에 여러 fragment가 경쟁할 수 있음 |
Coverage와 보간
clip triangle
-> viewport transform
-> sample coverage
-> perspective-correct attribute interpolation
-> fragment shader
-> depth / stencil / blend
-> color and depth attachments래스터라이저는 각 sample이 삼각형 내부인지 edge function으로 판정합니다. fragment shader로 들어가는 UV, vertex color, normal 같은 attribute는 barycentric weight로 보간됩니다. 원근 투영 뒤에는 단순한 screen-space 선형 보간이 틀어지므로, UV처럼 원근에 따라 달라져야 하는 값은 보통 1 / w를 반영한 perspective-correct interpolation을 씁니다. screen-space position이나 flat material ID처럼 보간하면 안 되는 값은 noperspective 또는 flat 같은 보간 규약을 의도적으로 선택합니다.
MSAA는 pixel 내부의 여러 sample 위치로 coverage와 depth/stencil을 더 세밀하게 판정합니다. 그러나 API와 shader 설정에 따라 fragment shader가 pixel당 한 번 실행되고 결과만 sample에 적용될 수도, sample마다 실행될 수도 있습니다. "MSAA를 켰으니 모든 texture sample도 더 촘촘해진다"는 뜻은 아닙니다.
실행 순서가 바뀌는 지점
| shader 또는 상태 | 바뀌는 점 | 성능/결과 영향 |
|---|---|---|
| depth write + opaque | 앞선 depth가 뒤 fragment를 줄일 수 있음 | overdraw가 큰 장면에서 유리 |
discard / alpha clip | 보이지 않을 fragment를 shader 안에서 버림 | backend에 따라 early depth 이점이 줄 수 있음 |
| fragment depth 출력 | shader가 depth를 직접 바꿈 | 깊이 테스트를 미리 확정하기 어려움 |
| blending transparent | 기존 color를 읽어 합성 | draw 순서와 bandwidth가 중요해짐 |
| per-sample shading | sample마다 shader 실행 | 경계 품질은 좋아질 수 있지만 비용이 커짐 |
early depth/stencil은 모든 shader에서 보장되는 단계가 아닙니다. discard, depth export, memory side effect, 특정 blend/coverage 설정이 있으면 GPU가 fragment shader 뒤로 테스트를 미루거나 두 번 검사할 수 있습니다. alpha-tested foliage처럼 depth를 쓰는 material은 opaque depth pass와 main pass가 같은 alpha cutoff, texture mip, vertex displacement를 사용해야 두 pass의 silhouette가 어긋나지 않습니다.
병목과 실패 신호
| 증상 | 먼저 볼 값 | 흔한 원인 |
|---|---|---|
| 카메라가 가까워질수록 급격히 느려짐 | fragment invocations, render target 해상도 | fill-rate 또는 texture bandwidth |
| 같은 영역을 여러 번 그려 느림 | depth complexity, transparent layer 수 | overdraw와 depth write 부재 |
| UV가 멀리서 휘어 보임 | interpolation qualifier, clip-space w | perspective-correct 보간 누락 |
| MSAA 경계가 기대보다 거침 | sample count, alpha-to-coverage, shader frequency | coverage만 늘고 shader는 pixel rate인 경우 |
| 작은 삼각형이 많은 장면이 느림 | primitive/vertex 처리 시간 | fragment 병목이 아니라 geometry 병목 |
화면의 색이 맞는다고 fragment 단계가 싼 것은 아닙니다. frame capture에서 primitive 수, fragment invocation, depth test 결과, attachment read/write를 함께 보고 정점 병목과 fill-rate 병목을 구분해야 합니다.
참고 링크
1 sources