Quick Reference
| convention | projection과 depth | clear / compare | 주의점 |
|---|---|---|---|
| 일반 Z | 가까울수록 작은 depth | 1.0 / LESS | near가 작으면 먼 곳 정밀도 손실 |
| reversed-Z | 가까울수록 큰 depth | 0.0 / GREATER | projection, clear, compare를 모두 함께 변경 |
| 투명 pass | depth test는 보통 유지 | write는 보통 끔 | 정렬 문제는 별도 해결 |
z-fighting 대응 순서:
겹친 geometry 제거 -> near를 멀리 / far를 좁게 -> depth format 확인 -> projection convention 확인구조
깊이 버퍼는 화면 각 위치에서 지금까지 가장 가까웠던 fragment의 깊이를 저장합니다. 새 fragment가 들어오면 기존 깊이와 비교하고, 더 가까우면 색과 깊이를 갱신합니다.
if newDepth < storedDepth:
color = fragmentColor
storedDepth = newDepth이 과정 덕분에 뒤에 있는 물체를 먼저 그려도 앞 물체가 최종적으로 보일 수 있습니다.
depth 값이 화면 거리와 선형으로 대응한다고 가정하면 안 됩니다. 일반 perspective projection은 near plane 부근에 정밀도를 많이 배정합니다. 그래서 far를 줄이는 것보다 near를 조금 멀리 옮기는 쪽이 z-fighting을 크게 줄이는 경우가 많습니다.
Z-fighting
z-fighting은 두 표면의 깊이가 너무 가까워서 depth buffer가 어느 쪽이 앞인지 안정적으로 구분하지 못할 때 발생합니다. 멀리 있는 평면, 겹친 decal, 너무 넓은 near/far 범위에서 자주 보입니다.
해결 기준
| 상황 | 대응 |
|---|---|
| near plane이 너무 작음 | near를 가능한 멀리 둠 |
| far plane이 너무 큼 | far를 필요한 범위로 줄임 |
| 표면이 겹침 | geometry offset 또는 decal 방식 변경 |
| 멀리서 깜빡임 | depth precision 재검토 |
| 투명 물체 | depth write와 정렬 정책 분리 |
depth precision은 선형으로 고르게 분포하지 않는 경우가 많습니다. 일반적인 perspective projection에서는 near plane 근처 정밀도가 높고 멀수록 정밀도가 떨어집니다.
reversed-Z는 0..1 depth convention과 floating-point depth buffer에서 먼 거리 정밀도를 더 잘 활용하는 대표 패턴입니다. 다만 projection matrix, depth clear, compare op, shadow/depth resolve가 하나라도 일반 Z 상태로 남으면 화면 전체가 뒤집히거나 depth test가 전부 실패합니다.
주의할 점
z-fighting을 단순히 표면을 아주 조금 띄워 해결하면 카메라 거리나 스케일이 바뀔 때 다시 깨질 수 있습니다. projection near/far, depth format, 렌더링 순서, decal 기법을 함께 봐야 합니다.
투명 물체는 depth test와 depth write 정책이 불투명 물체와 다릅니다. 투명도를 쓰면 깊이 문제와 정렬 문제가 같이 생길 수 있습니다.
decal처럼 거의 같은 표면을 의도적으로 겹치는 경우는 무작정 vertex를 밀기보다 depth bias, polygon offset, 전용 decal pass 중 무엇이 현재 projection과 shadow pass에도 일관된지 확인합니다. 카메라 거리에 따라 달라지는 상수 offset만으로는 재발을 막기 어렵습니다.
참고 링크
1 sources