핵심 정리
| 요소 | 의미 |
|---|---|
| Stencil buffer | 픽셀마다 작은 정수 값 저장 |
| Stencil test | 현재 값이 조건을 만족하는지 검사 |
| Stencil write | 통과한 픽셀에 새 stencil 값 기록 |
| Masking | 특정 영역만 그리거나 제외 |
| Outline/Portal | stencil로 경계나 통과 영역 제어 |
pass 1: object area writes stencil = 1
pass 2: draw effect only where stencil == 1구조
stencil buffer는 depth buffer처럼 화면 위치마다 값을 저장하지만, 깊이 값이 아니라 작은 정수 마스크를 저장합니다. 렌더링할 때 현재 픽셀의 stencil 값이 조건을 만족해야 fragment가 다음 단계로 갈 수 있습니다.
if stencilTest(storedStencil, reference):
draw fragment
maybe update stencildepth test가 “앞뒤 가림”을 판단한다면, stencil test는 “이 픽셀이 특정 영역에 속하는가”를 판단합니다. 둘은 함께 쓰이는 경우가 많고, 렌더 상태 순서에 따라 결과가 달라질 수 있습니다.
두 pass 패턴
가장 흔한 사용법은 먼저 마스크 영역을 stencil에 기록하고, 다음 pass에서 그 값이 있는 곳만 그리는 방식입니다.
1. mask mesh draw
color write off
stencil write 1
2. effect draw
stencil test equal 1
color write on이 패턴으로 거울, portal, outline, UI clipping, decal 제한 영역을 만들 수 있습니다. 반대로 특정 영역을 제외하고 그리려면 not equal 조건을 씁니다.
선택 기준
| 상황 | stencil 사용 |
|---|---|
| 특정 mesh 내부에만 효과 표시 | 적합 |
| portal이나 mirror 영역 제한 | 적합 |
| outline을 원본보다 크게 다시 그리기 | 적합 |
| 단순 rectangle UI clipping | scissor나 UI mask가 더 단순 |
| 부드러운 alpha mask | stencil보다 texture mask |
stencil은 픽셀 단위로 딱 끊기는 마스크에 강합니다. 부드러운 경계, feather, gradient가 필요하면 alpha texture나 별도 mask texture가 더 적합합니다.
주의할 점
stencil 값은 화면 전체에서 공유되는 render state 자원입니다. 어떤 pass가 값을 쓰고 지우는지 명확하지 않으면 이후 pass가 예상치 못한 영역에서 실패할 수 있습니다.
또 depth test, depth write, stencil write의 조합이 결과를 바꿉니다. 마스크를 쓰는 pass에서 color write를 끄더라도 depth write가 켜져 있으면 뒤쪽 렌더링을 막을 수 있습니다.
참고 링크
1 sources