본문 바로가기
컴터/OpenGL

[OpenGL] Z-buffer method

by 나 진짜 못차마 2023. 6. 10.
728x90

경북대 '컴퓨터그래픽스' 강의 백낙훈 교수님의 강의를 듣고 복습하기 위한 게시글입니다.

게시글의 내용은 강의 또는 구글링을 통해 공부하였습니다.

이미지 자료는 출처를 밝히거나 직접 그려 사용하였습니다

OpenGL을 이용하여 2개의 traingle을 그렸을 때 겹치는 부분이 생긴다고 가정하자.

그럼 2개의 Draw과정이 생기는데 이는 무조건 나중에 그린 삼각형이 먼저 그린 삼각형을 덮게 된다.

(깊이 정보을 주지않았다는 가정하에)

 

이러한 깊이 문제를 다루기 위해 왼손좌표계를 사용한다.

왼손 좌표계에서의 깊이(z)는 카메라에서의 거리가 멀어질 수록 값이 커지고, 가까울 수록 값이 작아진다.

[-1.0 , +1.0]


Painter's algorithm ( = depth sorting)

화가가 그림을 그릴 때처럼 먼 곳에 있는 것을 먼저 그리고 가까운 것을 그릴 때는 이전에 그린 것을 덮어서 그리는 기술과 같다는 것으로,

depth 기준으로 sorting 하여 뒤쪽 object부터 , 앞쪽 object 순서로 그린다.

하지만 이런 방법은 아래 그림과 같은 복잡하게 얽혀있는 문제는 해결하지 못한다.


Z-buffer method

픽셀 단위의 하드웨어 구현이다.

픽셀에는 color 값(R, G, B, A)이 있는데 거기다 depth 값, Z를 추가하는 것이다.

(R, G, B, A, Z)

object를 그릴 때마다, 픽셀 하나하나 depth test를 한다.

새로운 object가 더 가깝다면 그 object로 update하고,

아니라면 update하지 않고 현 상태를 유지한다.

처음 depth = +1.0 으로 초기화하고 시작한다.

그림과 같이 z, depth가 주어지고 depth를 검사하는 순서가 1, 2, 3, 4 로 정해졌다고 가정해보자.

[1]

초기화 depth 값 +1.0 보다 z = 0.98 이 작으니 update 해준다.

[2]

현재 depth 값 0.98 보다 0.5가 작으니 update 해준다.

[3]

현재 depth 값은 0.5 인데,

검사하는 depth 값, 0.7 은 이보다 큰 값이기 때문에 update하지 않고 현 상태를 유지한다.

[4]

이전 검사와 마찬가지로 현재 depth값과 비교하여 진행한다.

장점 :

Z-buffer method의 장점은 object가 z(depth)값에 대해 sorting 되어 있을 필요가 없다.

그리고 하드웨어 구현으로 매우 빠르게 진행된다.

단점 :

픽셀에 z 값을 추가함으로써 추가 메모리가 필요하다.

픽셀당 (R, G, B, A) 각 8bit씩, 총 32bit = 4byte가 필요하다.

z buffer( = depth buffer)는 정밀도를 위해 픽셀 당 24~32bit ( 3~4byte)가 필요하다.

초기에는 하드웨어 비용 문제 때문에 잘 쓰이지 않다가 최근에는 비용 문제가 해결되고 가장 잘 쓰이는 방법이 되었다.

Z- buffer 하드웨어 설계

z 좌표(깊이)는 좌표로 해석할 때는 x, y 와 마찬가지로 -1.0 ~ +1.0 로 설정한다.

하지만 저장될 때는 framebuffer 비슷하게 저장되어야한다.

framebuffer 에서 (R, G, B, A)의 색상 저장 값은 0.0 ~ 1.0 값으로 저장된다.

여기에 z 값이 추가 되려면 마찬가지로 0.0 ~ 1.0 값으로 저장된다.

다시 말해, View Volume 좌표로 볼 때는 -1.0 ~ +1.0 으로 되나, window 좌표로 변환할 때는 0.0 ~ 1.0 정수로 바꿔서 저장된다. (R, G, B, A , Z) 세트니까.

그래서

각 8bit씩 사용하는 RGBA의 실제 저장은 0~255 integer 값,

24(~ 32)bit 를 사용하는 Z의 실제 저장은 0~(2^24 - 1) integer 값으로 저장된다.

( 0.0 이면 0 , 1.0 이면 24bit일 때 가장 큰 수 2^24-1 로 비례해서 저장된다.)

OpenGL에서 Z-buffer를 default로 사용하지 않는다.

함수를 추가해줘야 한다.

void func() {
...
glEnable(GL_DEPTH_TEST);
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
...
}
728x90

'컴터 > OpenGL' 카테고리의 다른 글

[OpenGL] Look-At, Orthographic Projection  (2) 2023.06.10
[OpenGL] VBO(Vertex Buffer Objects)  (2) 2023.06.10
[OpenGL] Back face Culling  (0) 2023.06.10
[OpenGL] Double Buffering  (0) 2023.06.10
[OpenGL] Graphic Pipeline - Programmable Pipeline  (0) 2023.06.10