본문 바로가기
게임 개발/[D3D_Portfolio] DirectX3D 팀 포트폴리오 작업일지

18. 그림자 완성

by 헛둘이 2023. 10. 7.

광원에 의한 그림자는 모두 Depth Map 기반으로 구현하였다.

 

* Depth Map이란 ? 물체의 깊이값을 기록해두는 하나의 텍스쳐를 의미한다. 

- 물체가 그려지기 전 RenderShadow라는 함수를 통해 그림자를 그려줄 물체의 깊이값을 텍스쳐에 기록해둔 후,

빛을 적용할 때, 그 물체가 다른 물체에 가려져있는지를 Depth Map을 통해 확인해서 가려진 부분의 픽셀을 어둡게 해주는 원리이다.

 

- 이 Depth Map에 깊이를 기록할 때 유념해야 할 것은 빛의 위치에서 물체의 깊이값을 측정해야 하는 것이다.

- 빛이 그려질 때 이 카메라의 뷰행렬, 투영행렬을 곱한 VP행렬을 상수버퍼로 GPU로 넘겨주어, 셰이더에서는 Depth Map에 기록된 깊이값과 Vertex Shader로부터 넘겨받은 빛이 적용될 픽셀이 가진 위치값을 VP행렬을 통해 빛 위치의 좌표로 변환하도록 했는데, 그 위치를 통해 깊이 맵에 저장된 값과 해당 픽셀의 깊이를 계산한 후 기록된 깊이보다 더 뒤에 있다면 가려진 것이니 0.5를 곱해 어둡게 그려지도록 했다.

 

처음에는 무작정 구현하느라 전역으로 렌더타겟을 하나 더 추가했으나, 그림자를 그려주는 것은 각각의 빛이 계산될 때 처리해주기 때문에 전역으로 두기엔 씬마다, 맵마다 유동적인 개수의 빛을 파악할 수 없었다.

이 개념을 쉽게 구현하기 위해 특정 각도를 바라보는 카메라를 빛의 생성자에서 만들어주도록 했다.

 

문제점은 한 가지 더 존재했는데, 매 프레임 Depth Map이 그려지기 때문에 프레임 저하가 발생했다.

그래서 팀 회의를 통해 알아낸 해결책은 움직이지 않는 물체의 경우 씬이 최초 로딩될 때 Depth Map을 한 번만 갱신하고, 움직이는 물체는 실시간으로 갱신하는 식으로 하면 어떨까 하는 것이었다.

 

결과는 성공적이었다!

우리 프로젝트는 정적인 물체가 90% 이상을 차지했기 때문에 결과적으로 프레임 저하를 해결할 수 있었다.

댓글