(사실 이해했는지 모르겠다. 어렴풋이 느껴질 뿐... 그래도 그 느낌을 정리한다.)
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
- 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개를 받아서,
- 근데 얘는 알파 채널이 따로 없는 24비트 비트맵이여서, 쉐이더에서 clip을 넣어주었다.
연습 문제 8
- 일단 PSO는 이렇게
- 그리고 복잡도를 나타내는 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 게임 프로그래밍 입문
'Programming > D3D12' 카테고리의 다른 글
[책공부] Compute Shader + chap 13 연습 문제 (0) | 2024.02.02 |
---|---|
[책공부] Geometry Shader + chap 12 연습 문제 (0) | 2024.01.30 |
[책공부] Blend 예제 + chap 10 연습 문제 (0) | 2024.01.16 |
[책공부] Texturing 예제 + chap 9 연습 문제 (0) | 2024.01.13 |
[책공부] Lighting 예제 + chap 8 연습 문제 (0) | 2024.01.11 |