Post Lists

2018년 12월 11일 화요일

Shadow Rendering in Deferred Shading 생각

https://gamedev.stackexchange.com/questions/139545/how-do-modern-game-engines-handle-many-shadow-casting-lights

이 글로부터 어떻게 Shadow를 관리하는지에 대해서 광범위하게 알 수 있다.

첫 번째 답변은 언리얼 엔진에서 어떻게 하는지에 대해서 짤막하게 알려준다.

현재 나에게 가장 좋은 답변은 마지막 답변인데,
여러개의 light에 대한 Shadow Casting을 해야할 때, 그러한 것들을 어떻게 효율적으로 다뤄야할지를 알려준다.

Shadow가 구현하기 어려운 만큼, 성능을 향상시키기 위해서 여러가지 Optimization에 들어가게 되는데,

우선 나의 작은 엔진을 위해서, Shadow Mapping을 할 수 있는 Texture의 개수를 제한해야겠다.

왜냐하면 나의 Deferred Rendering Engine에서
Second pass의 lighting 계산시, 현재 uniform 변수로 지정되어 있는 것들이 많이 있는데,
Light만큼의 Shadow Map을 선언하기가 어려울 것 같기 때문이다.

그러니까 예를들어,

DirectionalLight  dLight[10];
sampler2D dLightShadowMap[10];

PointLight pLight[100];
sampler2D pLightShadowMap]100];

SpotLight sLight[20];
sampler2D sLightShadowMap[20];

요렇게 되는데, 저렇게 texture sampler를 선언하고, 저러한 모든 shadowmap을 그리려고 한다면 엄청난 성능 저하가 올 것이다.

그래서 현재 shadowMap의 개수를 제한해서, 내 성능에 감당할 수 있게 만들자.

아마 나중의 작업까지 고려한다면 작업 프로세스는 이렇게 될 것이다.

1. Shadow Map Texture 제한하기
2. View Frustum Culling 등 공간 분할 기법을 이용하여 Shadow Map Rendering 성능 향상
    -> Shadow Map Texture 개수 더 올릴 수 있음
3. Static and Dynamic Object 분할
   Static and Dynamic Lighting 분할
   Lighting Baking 활용하여 Shadow Map Texture 사용을 줄일 수 있음
   그리고 현재 엔진 editor에서 오브젝트가 움직이지 않을 때는 static으로 바꾸고
   사용자가 edit하려고 한다면, dynamic으로 바꾸어, shadow map을 동적으로
   렌더링하게끔 한다. 그리고 다시 안움직이면 static으로 전환.

아마 내 생각에는 3번이 현재 게임 엔진들에서 사용하는 기법이 아닐까 추측한다.
왜냐하면 여러가지 오브젝트가 있는 상황에서 항상 실시간으로 shadow map을 만든다는 것은 성능 저하에 큰 역할을 할 것이기 때문이다.

내 생각에는 3번까지는 현재 어려울 것 같고.
1번을 현재 개발하고, 나중에 2번의 view frustum culling 기법을 적용시킬 때 까지가
단기 목표가 되겠다.

그리고 나중에 시간이 지나서 내 엔진이 좀 더 발전하여 static and dynamic을 구분하여 할 수 있다면, 3번의 기능을 구현하여 좀 더 쉽게 shadow casting을 할 수 있을 것이다.






댓글 없음:

댓글 쓰기