Programming/D3D12

[책공부] Stencil 예제 + chap 11 연습 문제

Dorasima 2024. 1. 23. 13:54

(사실 이해했는지 모르겠다. 어렴풋이 느껴질 뿐... 그래도 그 느낌을 정리한다.)

 

1. Depth - Stencil은 GPU에서 작업 해준다. 

- 얘도 RenderTarget Buffer와 1대1(?)로 대응이 되는 Buffer이고, App에서 규칙과 파라미터를 정해서 던지면 GPU가 Depth-Stencil Buffer에 값을 넣든지, 조건을 확인하든지... 요청에 맞춰서 렌더링을 해준다.

- Blend와 마찬가지로 PSO으로 관리를 하고, 렌더링 파이프라인에 적용하는 것이다.

- D3D12_DEPTH_STENCIL_DESC 구조체를 이용해서 그 동작을 정의한다.

- 그래서 그 동작이 뭐냐? Depth 동작과 Stencil 동작이 따로 작동한다.

- 각각 Depth - Stencil 버퍼에 계산된 값을 넣던가 혹은 갱신을 하던가

- 혹은 Mask 값, App에서 정해준 Ref값들을 비교 Func을 이용해서 Rendering을 할지 결정하던가

- 결론은 이러한 Depth-Stencil 규칙들을 가진 PSO 들을 목적에 따라서 PipeState에 적용하면서 이런저런 시각적 효과를 내는 것이다.

 

2. App에서 해줘야 하는 것

- 일단 PSO에 원하는 동작을 하는 D3D12_DEPTH_STENCIL_DESC 를 정의해서 맴버로 넣어줘서 만들어야 한다.

- 원하는 Model, Materials 등을 원하는 모습으로 렌더링 할때, PSO와 그에 맞는, Stencil Ref 값을 ID3D12CommandList로 걸어주면서 Rendering 요청을 걸면 된다.

 

3. 언급할 만한 예제에서 사용한 방법(구조)

- 거울을 표현하는 예제이다.

- 일단은 DirectXMath에서 제공하는 Shadow Matrix와 Reflect Matrix를 이용해서, 반대 상의 모델을 World를 얻었다.

- RenderItem 구조가 있으니, World를 이용하여서 반대 상의 모델을 추가적인 구조 없이 그릴 수 있다.

- 이제 이걸 거울에만 그려야하는데, 예제에서는 거울이 그려지는 픽셀 위치에 Stencil 값을 갱신을 하여서, 해당 위치에 반대 상의 모델을 그리는 flag 역할을 하도록 만들었다.

- 그래서 거울 상을 제외한 (거울 처럼 보이게 하는 transparent model 포함) 다른 draw를 먼저 그린다.

- 그리고 거울 역할을 하는 곳에 Stencil Value를 1로 증가 시킨다.

(이 와중에 default depth 판정을 하여서 다른 opaque 물체에 자연스럽게 가려지게 한다.)

- 그 다음 반대 상의 모델을 그리는데,  Stencil Value 값이 1인 부분에만 (거울인 부분) 그리도록하는 D3D12_DEPTH_STENCIL_DESC 을 가진 PSO를 설정해주고, StencilRef값도 1로 설정을 해주고 draw 요청을 한다.

 

4. 연습 문제

(클릭하면 커집니다.)

 

연습 문제 3

 

연습 문제 4

 

연습 문제 5

얘가 Wall에서 Depth 판정을 하지 않는 친구
얘는 Wall에서 Depth 판정을 하는 친구

 

- Depth 판정을 결정하는 Depth Enable을 끄면, z가 0인 상태로 그려지는 것 같다.

- 그래서 D3D11_DEPTH_STENCIL_DESC.DepthEnable = false인 친구들은 App에서 DrawCall을 걸어준 순서대로 그려지고, 제일 마지막에 그려진 친구가 위로 올라오게 되는 듯 하다.

- 참고로 Skull이 제일 마지막에 그려지는데, Skull의 Depth도 판정을 끈다면

엄청 끔찍하다.

 

연습 문제 6

 무섭게 생겼다.

- DirectXMath에서 제공하는 XMMatrixReflect로 원래 skull의 World가 변화해도, Clockwise는 바뀌지 않으니

Frontface가 바뀌게 된다. 그래서 skull의 안쪽이 렌러딩이 될 것이고, 또 normal은 이상하게

(뇌 속에서 삼각형 하나만 거울에 비춰보면 바로 이해된다.)

 

연습 문제 7

 

- 예제에서 애니메이션으로 쓰라고 준 친구가 bmp이다. 그래서 예제 코드로는 ID3D12Resource로 바꿀 수 없는데,

- DirectXToolkit의 기능 중에 하나인 WICTextureLoader를 사용했다.

Home · microsoft/DirectXTK12 Wiki · GitHub

 

Home

The DirectX Tool Kit (aka DirectXTK12) is a collection of helper classes for writing DirectX 12 code in C++ - microsoft/DirectXTK12

github.com

 

(이전에 DirectX11에서는 DirectXTex를 사용했다.)

(그때는, Cmake인가 뭔가로 프로젝트 만들고, 라이브러리인가 dll 인가 만들어가지고 프로젝트에 추가해줬다.)

(DirectXToolkit도 비슷한 방법이 있지만)

- nuget이란 걸 사용하면, 프로젝트에서 사용하는 다른 코드 (lib, dll 등) 뭐 그런 것들을 그냥 다운로드로 받아서 사용할 수 있다고 한다. (천재들 참 많다...)

 

- 일단 여기 들어간다.

- 찾아보기에 directxtk12을 검색하면 이게 뜬다. 그 중에서 directxtl_desktop_2019를 쓰라고 문서에서 알려준다.

- 옵션은 잘 모르니까 걍 넘어가보자 ㄹㅇㅋㅋ

(설치 - 적용)

- 뭔가 패키지가 추가되었다고 한다... 뭔가 속전속결인데

 

- 요거 보고 따라해보자.  WICTextureLoader · microsoft/DirectXTK12 Wiki · GitHub

 

WICTextureLoader

The DirectX Tool Kit (aka DirectXTK12) is a collection of helper classes for writing DirectX 12 code in C++ - microsoft/DirectXTK12

github.com

-  헤더 인클루드 잘 된다... 옼 ("WICTextureLoader.h", "ResourceUploadBatch.h")

다행히 잘 작동한다.

- 이제 이걸 이용해서 사진 60개를 받아서, 

<iomanip> 과 ostream을 이용해서 반복문으로 Texture Resource를 가져왔고 / 대충 60프레임이면 0.01667초니까, 이때 heap index를 1씩 늘려주었다.
냅다 Shader Resource View Heap에 전부 박았다.

 

- 근데 얘는 알파 채널이 따로 없는 24비트 비트맵이여서, 쉐이더에서 clip을 넣어주었다.

... 이렇게 하는 거 아닌것 같은데

 

연습 문제 8

- 일단 PSO는 이렇게

                        Stencil을 무조건 기록하는 친구와                                                         StencilRef 값에 맞춰서 랜더링을 결정하는 친구로 나눈다.

- 그리고 복잡도를 나타내는 Material은 White1x1 텍스쳐와 albedo로 적당히 만들고

 

- Quad를 대충 생성하고 ,Quad 용 쉐이더도 따로 컴파일 한다.

(쉐이더는 삼각형 예제 쉐이더 처럼, Quad의 값을 그대로 넘겨주는 Shader를 작성하면 된다.)

- 렌더링은 먼저 원래 물체들을 전부 그리고나서,  RefCount에 맞춰서 Material을 가진 Quad를 차례대로 출력해준다.

 

연습 문제 9

 

연습 문제 10

- 개수를 세는 방법은... 모르겠다. 기록을 하는 방법은 이전 예제에서 했다. Depth에는 알맞는 DepthFunc을 걸어놓고, StencilFunc에서는 Always로 하고 PassOp에서 Increase를 하면 1씩 올라가서 통과한, 픽셀을 stencil buffer에 기록할 수 있는데.. 이걸 다시 가져오는 방법은 모르겠다. (위 예제 처럼 시각화 하는건 몰라도)

 

연습 문제 11

- Render Item을 따로 만들어주고, RenderLayer와 Constant Update만 신경써서 하면된다.

 

연습 문제 12

더보기

책 : DirectX 12를 이용한 3D 게임 프로그래밍 입문