오즈라엘님과 여러 이웃분들의 조언으로 좀더 보강하였습니다. (그래도 아직 미흡해 보이지만) 이전에는 MRT를 모두 D3DFMT_A8R8G8B8 포맷으로 잡아 모든 정보를 다 넣었던 것에 비해 이번에는 다른 분들의 조언에 따라 Diffuse D3DFMT_A8R8G8B8, Normal D3DFMT_G16R16F, Depth D3DFMT_R32F 식으로 포맷을 정하고 수정해봤습니다.

여기서 삽질이 좀 많았지만 어찌어찌 된 것 같습니다. 특히 Normal을 XY값만 보관하는 것에서 조금 삽질이 많았습니다. 킬존에서는 z = sqrt( 1 - x^2 - y^2 ) 식을 사용하고 있다고 하는데, 이 방법은 z값이 무조건 양수로 나오더군요. 이거 때문에 조명 관련 처리를 하는데 제대로 표시가 안돼 상당히 애를 먹었습니다. 다른 방법을 알아 보던 중 nVidia 개발자 사이트에서 이 문제를 해결한 공식이 있길래 적용해서 사용 중입니다. ( 다른 분들은 어떠신가요?? )

pX = X / ( 1 + Z )
pY = Y / ( 1 + Z )

denom = 2 / ( 1 + pX * pX + pY * pY )
X = pX * denom
Y = pY * denom
Z = denom - 1

Normal 관련해서 정보를 뒤지던 중 Normal 압축 방법에 대해 다양한 방법을 볼수 있는 곳이 있더군요. 참고해보시면 좋을 것 같습니다. [ Compact Normal Storage for small G-Buffers ]

실행 화면


Diffuse ( MRT0 )
D3DFMT_A8R8G8B8


Normal ( MRT1 )
D3DFMT_G16R16F
half4( n.x / ( 1 + n.z ), n.y / ( 1 + n.z ), 0, 0 )


Depth ( MRT2 )
D3DFMT_R32F
z / w


Normal( Output  )
denom = 2 / ( 1 + enc.x * enc.x + enc.y * enc.y );
n.x = enc.x * denom; n.y = enc.y * denom; n.z = denom - 1;


Depth ( Output )

+ Recent posts