오즈라엘님과 여러 이웃분들의 조언으로 좀더 보강하였습니다. (그래도 아직 미흡해 보이지만) 이전에는 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 )
  1. BlogIcon 구차니 2010.09.01 20:48 신고

    음.. 다른건 모르겠고.. FPS가 출력되면 참 좋을꺼 같아요 ㅎ
    성능이 향상되었다는걸 보여주고 싶으신거 같은데 전에꺼랑 비교하기에는 FPS 만한게 없을꺼 같아요

    • BlogIcon 친절한티스 2010.09.02 08:30 신고

      음... 비교를 해보려면 광원을 잔뜩 집어넣고 프레임을 찍어봐야 할텐데...
      아직 기존 렌더러에서 광원 처리를 제대로 안해놔서 =ㅅ=..
      기회되면 비교 영상 찍어볼게요~

    • BlogIcon 구차니 2010.09.03 22:13 신고

      앗 주의깊게 다시보니 예전에도 FPS는 출력되고 있었네요 ^^;

  2. BlogIcon ozlael 2010.09.01 21:43

    앗. 부호문제를 잊고 말씀 안드렸었네요 -ㅈ-;; 처음에는 부호를 무조건 음수로 바꿔사용했습니다만, 그걸로 부족한 경우가 있더군요.
    카메라를 지면 가까이서 대각선 위를 바라볼 시 지면의 카메라 공간 기준 노말의 부호가 바뀌는 경우가 있습니다. 그래서 저희 엔진은 후루꾸로 Gbuffer Depth에 노말z의 부호를 저장합니다 -ㅈ-

    • BlogIcon 친절한티스 2010.09.02 08:31 신고

      ㅋㅋㅋ 역시 그랬군요. 전 제가 잘못하고 있는줄 알고 굉장히 고민했어여...
      Depth에 같이 저장하는 방법도 있었군요

+ Recent posts