Quick Flow
스텐실 첨부 준비·0으로 clear
→ 마스크 패스: ALWAYS, REPLACE, 쓰기 허용
→ 색 패스: EQUAL, KEEP, 쓰기 차단
→ 스텐실 상태·색/깊이 마스크를 다음 패스 계약으로 복원스텐실은 픽셀별 정수 표식을 저장합니다. 비교에 쓰는 mask와 기록을 허용하는 write mask는 다릅니다. 깊이 테스트의 성공 여부도 스텐실 연산 선택에 관여합니다.
상태 인벤토리
| 상태 | 기본값 | 가능한 값·역할 |
|---|---|---|
| STENCIL_TEST | 비활성 | 버퍼가 있는 패스에서 활성화 |
| func | ALWAYS | NEVER·LESS·LEQUAL·GREATER·GEQUAL·EQUAL·NOTEQUAL·ALWAYS |
| ref | 0, 저장 비트 범위로 제한 | 비교 기준과 REPLACE 값 |
| compare mask | 모든 비트 1 | ref와 저장값 양쪽에 AND |
| write mask | 모든 비트 1 | 어느 비트를 수정할지 |
| sfail/dpfail/dppass | 모두 KEEP | 스텐실 실패/깊이 실패/통과의 연산 |
| clear value | 0 | clear 시 write mask·scissor 영향 |
연산은 KEEP·ZERO·REPLACE·INCR·INCR_WRAP·DECR·DECR_WRAP·INVERT입니다. INCR/DECR의 포화와 WRAP의 순환을 구분합니다. 깊이 테스트가 비활성이거나 깊이 저장소가 없으면 dpfail은 사용하지 않고, 스텐실을 통과한 프래그먼트에는 dppass를 적용합니다. 비교식은 마스크한 ref와 마스크한 저장값의 관계이므로 LESS를 저장값이 더 작다는 의미로 뒤집어 읽지 않습니다.
두 패스 예제
// GL 3.3 Core: 스텐실 첨부가 있고, 각 draw의 프로그램·VAO는 준비되어 있습니다.
glEnable(GL_STENCIL_TEST);
glStencilMask(0xFF);
glClearStencil(0);
glClear(GL_STENCIL_BUFFER_BIT);
glStencilFunc(GL_ALWAYS, 1, 0xFF);
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
// 마스크가 될 도형을 draw합니다. 스텐실·깊이 조건을 통과한 곳에 1을 기록합니다.
glStencilMask(0x00);
glStencilFunc(GL_EQUAL, 1, 0xFF);
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
// 1로 표시된 영역에만 색 도형을 draw합니다.0xFF는 8비트 표식을 전제로 한 예입니다. 마스크 패스의 색을 숨기려면 color mask를 따로 바꾸고 후속 패스 전에 복원합니다. 깊이 테스트가 필요한 마스크인지도 명시합니다. 의도적으로 두 draw를 생략한 호출 순서 발췌이며 장면의 버퍼·셰이더 생성 코드는 별도로 필요합니다.
실패와 버전
write mask를 0으로 둔 다음 프레임에 clear하면 기대대로 0으로 지워지지 않습니다. 스텐실 첨부가 없으면 상태만 켜도 표식은 저장되지 않습니다. 앞뒤 면별 동작이 필요한 경우 Separate 계열의 face 인수를 맞춥니다.
기본 스텐실은 1.0부터이고 별도 앞뒤 면 설정은 2.0 코어 경로입니다. 구형 예제에서 여러 패스로 흉내 낸 양면 동작을 현대 API로 옮길 때 cull·depth 상태까지 함께 비교합니다. 알고리즘 예시는 Graphics 스텐실에 있습니다.
참고 링크
4 sources