상세 컨텐츠

본문 제목

[포니 게임 개발] 25

프로그래밍/포니게임개발

by ∫2tdt=t²+c 2013. 5. 26. 08:04

본문





Deferred Rendering을 적용하기 위해 렌더링 코드를 밑바닥부터 전부 뜯어고쳤습니다. 흙흙

근데 Forward말고 딱히 Deferred Rendering을 적용할 필요가 있었는가? 하면 잘 모르겠네요...

그렇게 필요성이 있는지는 모르겠습니다.


다음과 같은 의식의 흐름 속에서 Deferred Rendering을 사용하기로 결정...


1. 게임 성격상 카툰 렌더링이 컨셉이기에 동적인 라이팅이나 화려한 이펙트는 필요없다

2. 하지만 다양한 후처리 효과에 이미 노말맵, 벨로시티맵, 깊이맵을 사용하고 있다.

3. 이미 쓰고 있는 렌더투텍스쳐 기술이기에 큰 성능 저하 없이 Deferred Rendering을 사용할 수 있을거 같다

4. 게다가 밤 장면에 다양한 광원들이 사용되면 멋질거 같다



Deferred Rendering 자료 찾고 구현하는데만 꼬박 이틀이 걸린거 같네요.

http://www.slideshare.net/agebreak/ndc11-deferred-shading

http://www.storyq.net/slide_boxes/38624

가장 큰 도움이 되었던 자료입니다.


간단하게 Deferred Rendering을 설명하자면,

기존의 렌더링 방식에서는 렌더링되는 폴리곤의 각 픽셀마다 텍스쳐값을 계산하고 여기에 광원을 계산하여 곱해주고 더해주고 이런 저런 방식을 취해서 화면에 찍어낼 픽셀을 계산해냅니다.

문제는 이것이 오브젝트가 늘어나고, 라이트가 늘어나면 오브젝트마다 각각 광원을 계산해줘야하기 때문에, 계산량이 쭉쭉 늘어난다는 것이죠. 그래서 이 방식으로는 광원을 여러개 사용할 수 없습니다.


Deferred Rendering은 멀티렌더타겟을 이용해 1. 처음에 오브젝트를 렌더링할때, 오브젝트의 Diffuse 텍스쳐값, Normal값, 깊이값을 저장해두고. 2. 별도의 패스로 광원을 렌더링하는거죠. 먼저 계산해두었던 Diffuse, Normal Depth 정보를 이용해 광원이 뿌려질 위치에만 광원 계산을 하면 되고, 광원이 늘어난다고 해도 광원에 대한 계산만 늘어나기 때문에 수많은 광원을 쓸수가 있습니다.


참 좋은 아이디어인데, 구현할 때 무지 헤맸습니다.

처음에는 VertexDeclaration을 제대로 설정하지 않아줘서, 자꾸 버텍스가 뻑나는데, 그거 원인 모르고 삽질하며 시간을 날렸고, 두번째는 망할 W, W값으로 나누는걸 생략해서 헤맸습니다.


문제가 되었던 코드죠... 광원을 계산하는 부분 코드인데, 웹에서 돌아다니는 예제 코드에서는 저런 In.Position2.xy / In.Position2.w 짓을 안했습니다. w로 나눠줘서 투영하는 일을 생략. 했던게 아니고, 아마 하드웨어 상에서 지원하도록 설정했나봅니다. (아마 D3D 설정 중에서 TexCoord가 넘어갈때 자동으로 투영 계산되게하는게 있었던거 같은데... 그걸 설정안하고, w로 나눠주는것도 안했으니 자꾸 이상한 좌표의 텍스쳐를 참조할 수 밖에 없었던 거죠)


또다른 삽질실수는 D3DFVF_XYZRHW로 넘어가는 Vertex들은 버텍스 셰이더를 통과하지 않는다는 걸 깜박했던 겁니다. 버텍스 셰이더에서 Position2값을 설정하는 작업을 했었는데, 그냥 사각형 출력이라고 착각하고 D3DFVF_XYZRHW로 넘겼더니, Position2값이 전혀 설정되지 않아서 이상한 값이 넘어간거죠.


이렇게 온갖 실수가 어우러져서 이틀을 낭비(?!ㅠ)하게 만들었습니다. 근데 구현하면서 재미도 있었고 많은 것도 배운거 같네요ㅋ



전반적인 퍼포먼스는 Forward Rendering보다 아주 약간 떨어졌습니다. 하지만 동적인 다수의 광원을 이용한다는 게 보통 이득인가요ㅋ. 약간 문제점은 노말맵 정밀도의 문제입니다. 흙. 화면이 빠르게 이동할때는 상관없는데 천천히 이동할때 노말맵 오차로 조명값이 튀는 현상이 눈에 띕니다. R16G16인데 튀면 어쩌란 말이니 ㅠㅠ R32G32 같은 포맷은 없잖아 안될거야 아마 흙

광원을 많이 이용할 수 있게 되자, 모델링 파일도 수정하게 되었습니다. 3d모델에 광원을 포함할 수 있도록 기능을 강화했습니다. 이거 기능 강화하는 김에 모델 포맷도 바닥부터 뜯어고쳤네요.


굳이 수정사항을 정리하자면...


- 렌더링 엔진을 갈아치웠습니다. Deferred Rendering을 지원합니다.

- 엔진 교체로 오브젝트의 외곽선이 더 뚜렷하게 그려지게 되었습니다.

- 3d모델 포맷을 업그레이드했습니다. 이제 모델에 광원효과와 부착지점을 포함시킬 수 있습니다.

- 이제 3d모델에 뼈대 계층구조가 포함되어, 3d모델으로부터 이용해 뼈대 변환행렬을 계산해냅니다.

( 기존의 3d모델 포맷에는 뼈대 계층구조가 포함되어있지 않고, 애니메이션 포맷에 뼈대 계층구조가 포함되어있는 한계가 있었습니다. 이로인해 계층구조가 다른 모델에 동일한 애니메이션을 적용해도 적용이 안 되는 버그가 있었죠. 모델포맷을 수정하면서 이 문제점도 해결했습니다.)

- 같은 모델을 여러번 출력할때 뼈대 애니메이션을 여러 번 계산하지 않도록, 애니메이션 행렬 캐시를 적용했습니다.

- 3dsmax에서 확장된 3d모델을 내보내기할수 있도록 스크립트를 수정했습니다.


트와일라잇 뿔에 조명을 달아보았어요. 트와일라잇이 회전하면 그에 연결된 조명도 같이 움직이는걸 볼수가 있어요. 점 광원(Point Light)은 카툰셰이딩을 안했더니, 점 광원을 받으면 입체효과가 살아났다가, 없어지면 평평해 보이는 마법 아닌 마법이...ㅋ



관련글 더보기

댓글 영역