Game Develop

[DirectX11] DeferredRendering 본문

ComputerGraphics/DirectX

[DirectX11] DeferredRendering

MaxLevel 2021. 7. 19. 17:53

디퍼드렌더링이 뭔지에 대한 자세한 글이 아니라 실제 코드에서 전체적인 자원이동 흐름이 어떤건지 정말 간략하게 정리해놓은 글이다.  디퍼드렌더링이 뭔지는 대충 검색하면 많이 나오지만, 실제 코드로써 자원정의와 흐름을 모르면 써먹을 수 없기 때문에 예제 보면서 코드 한줄한줄 이해했다. 개인적으로 RenderTarget부분을 제대로 공부안했어서 시간이 좀 걸렸었는데 어쨋든 이기회에 많이 공부해서 다행이다. cpp코드로 hlsl코드 보면서 메모장으로 막 정리한거라 다른사람이 보기에는 많이 불편할것같다.

 

디퍼드렌더링은 기존의 포워드렌더링의 라이트계산을 압도적으로 줄여놓은 라이팅 최적화기법이다.

포워드렌더링같은 경우 N*M의 라이트계산을 해야한다. 하나하나 일일이 해줘야한다는것.

디퍼드렌더링은 각 오브젝트들의 디퓨즈,스페큘러,노말값 등을 각각의 텍스쳐에 다 기록해놓고, 최종적으로 각 텍스쳐를 이용해서 픽셀계산을 하고 렌더링을 한다. 각 텍스쳐를 이용해서 라이팅 계산전의 출력픽셀을 결정하고, 최종적으로 라이팅연산 렌더.(각 픽셀에 월드포지션값 저장되어있으니까..

 

각오브젝트들에는 임의의 GBuffer라는 셰이더를 셋팅한다. 그러면 이 오브젝트들의 디퓨즈,스페큘라,노말값들이 각각 텍스쳐형태(float4)로 파이프라인의 OM에 셋팅된다.

 

디퍼드라이팅셰이더에선 결국 각 텍스쳐 (뎁스,디퓨즈,스페큘라,노말) 에서 값 가져와서 계산후 최종 출력할뿐이다.
GBuffer에서 각 텍스쳐를 셋팅한다. 
GBuffer 셰이더에서 픽셀셰이더에서 리턴할때 각 값들을 SV_Target0~2로 리턴한다.

SV_Target으로 리턴하면 CPU단에서 OM에 셋팅한 RTV배열의 인덱스순서로 리턴된다.

위 과정을 거치면 각각의 RTV를 구했으니 SRV값을 뽑아와서 디퍼드라이팅셰이더에 넘겨준다.

srv배열은 0은 dev->srv(뎁스)고 나머지는 위 순서랑 동일.
셋팅한 srv배열은 디퍼드라이팅셰이더에서 사용.


GBuffer::struct PixelOutput
{
    float4 diffuse : SV_Target0; // OM의 RTV배열의 각 인덱스에 픽셀셰이더결과를 리턴.
    float4 specular : SV_Target1;
    float4 normal : SV_Target2;
};

그러면 OM에는 이 값들을 계속 가지고있고, CPU단에서 GetSRV해서 이 SRV자원을 픽셀셰이더에 전달.
그러면 디퍼드라이팅셰이더에서 이 SRV값들(뎁스,디퓨즈,스페큘라,노말) 이용해서 최종 렌더링하면끝.

 

 

좌측상단부터 시계방향순서대로, 깊이값텍스쳐,디퓨즈텍스쳐,노말값텍스쳐,스페큘라값텍스쳐이다...

 

몬스터들은 스펙큘라맵이 없어서 안보이는것이고, 디퓨즈맵에 그림자가 있는 이유는 디퓨즈맵에다가 깊이맵셰도우매핑을 적용해서 그런다.