Depth Testing
1. Depth Buffer란?
깊이 버퍼(Depth Buffer)는 렌더링 시 각 픽셀의 깊이값을 저장하는 버퍼로, 이를 통해 객체의 앞뒤 관계를 결정한다. 픽셀이 그려질 때마다 현재 그리려는 픽셀의 깊이값과 깊이 버퍼에 저장된 값이 비교되어, 조건에 맞으면 그리기를 수행하고 그렇지 않으면 무시한다.
2. Depth Testing 사용하기
깊이 테스트를 활성화하고 비활성화하는 방법은 다음과 같다.
- 깊이 테스트 활성화:
glEnable(GL_DEPTH_TEST);
- 깊이 테스트 비활성화:
glDisable(GL_DEPTH_TEST);
깊이 테스트를 활성화하지 않으면, 객체가 그려진 순서대로 마지막 객체가 앞에 나타나며, 이전 객체는 덮어쓰여지게 된다.
3. Depth Buffer 조작
깊이 버퍼는 다양한 방식으로 설정할 수 있다.
- 깊이 버퍼 업데이트 막기:
glDepthMask(GL_FALSE);
- 깊이 버퍼 초기값 설정:
glClearDepth(1.0f);
4. Depth Test 비교 연산자
깊이값 비교 방식은 glDepthFunc()
함수를 사용해 설정할 수 있다. 기본 값은 GL_LESS
로, 현재 그리려는 픽셀의 깊이값이 버퍼에 저장된 값보다 작을 때만 그리기가 수행된다.
사용 가능한 비교 연산자:
GL_ALWAYS
: 항상 그린다.GL_NEVER
: 절대 그리지 않는다.GL_LESS
: 깊이값이 작을 때만 그린다.GL_LEQUAL
: 깊이값이 작거나 같을 때 그린다.GL_GREATER
: 깊이값이 클 때 그린다.GL_GEQUAL
: 깊이값이 크거나 같을 때 그린다.GL_EQUAL
: 깊이값이 동일할 때 그린다.GL_NOTEQUAL
: 깊이값이 다를 때 그린다.
깊이값의 왜곡
깊이값 왜곡은 원근 투영(perspective projection)을 적용하면서 발생한다. 투영 변환 시 깊이값이 0에서 1 사이로 정규화되며, 이 과정에서 w
값으로 나누어지기 때문에 비선형적인 분포를 보인다. 일반적으로 가까운 영역에서 깊이값의 변화가 더 민감하고, 먼 거리에서는 차이가 적다.
이러한 깊이값 왜곡은 원거리 객체 간의 깊이 차이가 작아 Z-fighting 문제를 유발할 수 있다.
Z-fighting
1. Z-fighting 원인
Z-fighting은 두 객체의 깊이값 차이가 매우 작아, 서로 교차되는 부분에서 깊이 테스트의 결과가 불확실해지는 현상이다. 이러한 문제가 발생하는 주된 원인은 다음과 같다.
- near 값이 너무 작은 경우: 가까운 거리에 더 많은 깊이값 범위가 할당되어 원거리에서의 정밀도가 낮아진다.
- 면과 면이 너무 가까운 경우: 깊이값의 차이가 거의 없어 깊이 테스트에서 오류가 발생한다.
2. 해결 방안
Z-fighting 문제를 완화하기 위한 방법은 다음과 같다.
- near 값을 너무 작게 설정하지 않기:
near
와far
값을 적절하게 설정하여 깊이값 분포를 최적화한다. 예를 들어,0.01f
대신0.5f
같은 값을 설정해 본다. - 깊이 버퍼 정밀도 높이기: 더 높은 비트 깊이의 깊이 버퍼를 사용하면 깊이값의 정밀도가 향상된다.
- 객체 간 거리를 벌리기: 서로 인접한 면들이 겹치지 않도록 적절히 간격을 유지한다.
'Computer Graphics > OpenGL' 카테고리의 다른 글
OpenGL 정리 - 20. 프레임 버퍼 (Frame Buffer) (0) | 2024.10.25 |
---|---|
OpenGL 정리 - 19. 스텐실(Stencil), 블랜딩(Blending), 컬링(Face Culling) (0) | 2024.10.25 |
OpenGL 정리 - 17. 오브젝트 로더 구현 (Assimp) (1) | 2024.09.24 |
OpenGL 정리 - 16. Light Casters (0) | 2024.09.23 |
OpenGL 정리 - 15. Texture Map 적용 (0) | 2024.09.23 |