2020년 7월 1일 수요일

DirectX - Depth Precision Visualization

D3DXMatrixPerspectiveFovLH function 에서 긁어 온 것이다.

(x, y, z, 1) 를 위 행렬에 w곱하면 그 결과값은

$\left(xScale\cdot x,\ \ yScale\cdot y,\ \frac{\left(z\ -\ zn\right)\ \cdot \ zf}{zf\ -\ zn},\ \ z\right)$(xScale·x,  yScale·y, (z  zn) · zfzf  zn,  z)

여기에 결과값의 w 에 있는 z 를 결과값 전체에 나누면, x, y 좌표는 z = 1 인 평면으로 이동된다.

그리고 z 좌표는 0~1 사이로 정규화되며, 이 값을 깊이 혹은 d 라고 부른다.

RSState 는 이 d 를 계산하고, 이 값을 가지고 OMState 에서 보간을 하고 깊이 버퍼 처리를 하고 그런다.

만약 zn 이 0 이면 문제가 발생하니 예외로 치고, 다음의 예를 하나씩 보자.

zf = 1.001, zn = 0.001,

zn 과 zf 의 가운데 값일 터였을 0.501 이 D 에서는 1에 거의 가까운 값을 갖게 된다.

zf = 4.00, zn = 2.00

위의 예보단 낫지만, Z 에서의 중앙값은 D 에서 1에 치우친 값을 갖게 된다.

이게 무슨 의미를 가질까?

z 의 값이 zf 에 가까울 수록 넓은 범위의 z 값이 d 에서는 좁은 범위에서 표현이 된다는 것.

이는 선형 보간을 하면 답이 없는 결과를 얻게 된다는 소리이다.

그런데 어떤 인간이 float 의 표현방법을 보고 새로운 보간 방법을 떠올렸다.

8 exponent bits (지수) and 26 mantissa (가수) 로 float 는 처리된다.

근데 지수와 가수를 계산한 결과 값이 아니라, 지수와 가수를 대등하게 보아서 보간할 수도 있다.

2 exponent bits and 2 mantissa 에서는 다음과 같이 된다.

(여기선 biased 방식이 아니라 그냥 양의 2진수를 생각함)

0, 1, 2, 3, 4, 6, 9

부동 소수점 계산 방식을 이해한다면, 지수부가 커질수록 정확한 수 표기가 힘들고 수 간 범위가 커짐을 알 수 있다.

이를 그래프화 한게 위 사이트의 이 그래프다.

이것만 봐서는 별 생각이 없을지도 모른다.

0~1 순서를 뒤집어보자.

우와, z 값의 내용을 선형적으로 표현할 수 있게 되었다.

그래서 가까울 때 1, 멀때를 0 으로 설정하는 z reverse 를 사용한다.

문제는 -1~1 로 범위를 설정하는 opengl 에선 편법이 필요하다는 것.


이건 적용법

https://www.gamedev.net/forums/topic/693404-reverse-depth-buffer/


댓글 없음:

댓글 쓰기

List