유영천 프로그래머(@megayuchi )님 방송을 가끔 보는데...
그동안 공부했던 D3D12 책이 그다지 좋지 않다는.... 얘기를 들었다.
그래서
뭐라도 좀 해야겠다 싶어서 앱 구조라도 일단 예쁘게? 다시 짜보는 걸 해보도록 하겠다.
- 예쁘다의 기준은... 나중에 공부하면서 추가할 기능이... 예쁘게? 돌아가게 하는 거 ㅋㅋ
github - d3d12practice - solopractice
0. 일단 megayuchi 강의 샘플을 적당히 따라감
D3D12 프로그래밍-기초편 강의 | megayuchi - 인프런
megayuchi | 이제는 주류 그래픽 API의 자리가 D3D11에서 D3D12로 넘어간 것 같습니다. D3D12는 매력적인 기능들을 지원하지만 학습 난이도가 높은 편입니다. 하지만 차근차근 학습한다면 개인도 D3D12 API
www.inflearn.com
- D3D12 API와 어울리는 구조로 짜는 방법을 엿볼 수 있다.
- 완전 비동기 + 멀티스레드 특화 API를 위한 pooling을 많이 사용한다.
- DirectXAgility와 DirectXTex도 간단하게 사용한다.
(강의는 취직한 뒤 꼭 구매하겠습니다... 하핫)
1. D3D12 like(?) 하게 그려보기 위해, PSO caching을 해보기로 했다.




- 일단 지금은 ... 머 대충 박스 몇개, 사각형 몇개 출력하는게 전부니까 이렇게 문자열로 구분하는데,
- 나중가면 key가 여러개인 자료구조를 사용해야 하지 않을까...
2. 일단 World 느낌이 나게 Quad를 wireframe으로 그려보겠다.

-어... 이렇게 삼각형 느낌이 나면 안되는디
- geometry 쉐이더를 이용해서 다시 해봐야겠다.
3. Geometry Shader로 Tile 그리기.
- Geometry Shader로 만든 LineStream이... 안보인다 (해결함)

- 짜증난다... Culling이 일어나는건 아닌 것 같다. 순서를 뒤집어도 가로선은 잘 보인다.
- 윗줄을 다시 말하면... 저 (x < 0) (z < 0)부분에서 제멋대로 Culling이 일어난다(?) 라고 표현하는 느낌이다.
- UINT로 해서 그런거다 ㅋㅋㅋㅋㅋㅋㅋ


- 이렇게 x, y 축을 1좌표 마다 점을 그려서 넘겨주었다.

4. 좀 더 자연스럽게 GridTile 그리기



- 간격도 좀 넒혀주고 (25 정도?), 카메라 위치에 따라 적절히 새로 그려지게 했다.
(나중에는 카메라 위치에 따라, 그리지 않는 것도 하는게 좋을 듯?)
5. 파일 드래그 앤 드롭
- 일단 현재 목표는 3d model viewer 이다.
- 드래그 앤 드롭으로 모델 파일을 띄워보려고 한다.

- WndProc() 에서 WM_DROPFILES 메시지 일 때, <shellapi.h>에서 제공하는 DragQueryFile()을 이용하였다.
- 그 이전에

- 윈도우 속성에 WS_EX_ACCEPTFILES 확장 속성을 추가해준다.
6. Lighting을 하기 위한 Frame 별 CBV 따로 넘겨주기
- D3D12Renderer 가 App과 함께 가면서 렌더링을 하는데
- 카메라 위치나 월드의 조명 정보는 모든 object가 공유하니까 Render에서 관리하고, Object에 넘겨주는 식으로 한다.


- Object 별로 PSO와 Root Signature를 갖긴하지만... 포인터로 넘겨 받은걸 SetGraphicsRootConstantBufferView()로 걸어주기만 하는거니까.... 그다지 느린 작업은 아니라고 생각한다.
7. 모델 윤곽선 (outline) 그려보기
- 인접한 삼각형이 서로 카메라를 중심으로 dot값이 다르면, 그곳이 바로 윤곽선일 것이다.
- Geometry Shader에서 이를 해줄 수 있을 것이다.
- 삼각형의 인접 정보(Triangle Adjacency) 알아야하기 때문에, 원래 Mesh 정보를 나타내는 Indices의 Triangle list를 Triangle list with adjacency으로 바꿔줘야 한다.
Primitive Topologies - Win32 apps
Direct3D 10 and higher supports several primitive types (or topologies) that are represented by the D3D\_PRIMITIVE\_TOPOLOGY enumerated type. These types define how vertices are interpreted and rendered by the pipeline.
learn.microsoft.com
- DirectXMesh를 쓰고싶었는데... 자꾸 heap corruption이 나서 직접 만들어주기로 했다.



- 일단은 주변 삼각형을 위치(position)으로 검색하면서 채워넣어야 하기 때문에 unordered_map을 위한 hash를 만들고
- 원하는 동작은 triangle list 를 triangle list with adjacency로 바꾸는 것이다.


- list는 index 3개씩 1개의 삼각형을 만드는 특징을 가지고 있으니까
- 사이사이와 마지막에 인접점을 하나 끼워넣어주면 되는 것이다.
- https://learn.microsoft.com/ko-kr/windows/win32/direct3dhlsl/dx-graphics-hlsl-geometry-shader
기하 도형 셰이더 개체 - Win32 apps
기하 셰이더 개체는 전체 기본 형식을 처리합니다. 다음 구문을 사용하여 기하 도형 셰이더 개체를 선언합니다.
learn.microsoft.com
- 요런식으로 vertex position으로 검색이 가능하고 value로 삼각형 정보를 가지고 있는 map에서 인접 정보를 찾는 함수를 따로 만든다.


- 사이사이에 끼워 넣어주면 triangle list with adjacency 가 된다.


- 윤곽선을 그리는 Shader 코드는 다음과 같다.


- 이제 topology를 D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST_ADJ 으로 설정하고
- 이것저것 다 모델 정보에 맞는 정보로 그리면?

- 근데 고쳐야 할 점이 보인다.
- 삼각형 노멀과, 삼각형에서 카메라를 향한 방향이 어느 구역에서 (현상으로는 수직 근처) 그려지지 말아야할 구간이 그려진다.
- 고쳤다. Camera 로 방향을, 삼각형이 아니라 각 점에 대해 계산하고, 원래 삼각형 노멀이 카메라와 dot 가 음수면 그냥 날려버렸다.


8. Material은 Sub-Model 단위로 넘겨주기
- 시간에 따라 업데이트 될 수 있으니, 강의에 나온 pool 구조를 이용해서 업데이트 하기

- 이렇게 서브 모델 마다 머테리얼을 가질 수 있게 만들고
- 원래 Draw를 걸 때는 heap에 Texture 밖에 없었는데, Material 정보가 추가 되었으니,
- 서브 모델의 개수 만큼 Texture, Material 이 번갈아 가면서 bind 하게 된다.


- 이에 맞게, root signature 도 바꾸고, 쉐이더도 바꾼다.
(다른 자료형에 다른 버퍼라서 table entry를 그냥 하나 추가해주었다.)
- 그렇게 하면?

9. 좀 길어지는 것 같아서... 2편으로 옮긴다.
'Programming > D3D12' 카테고리의 다른 글
[일기장] 무작정 FBX SDK 사용해보기 (Material + Animation) (0) | 2024.05.05 |
---|---|
[일기장] 무작정 FBX SDK 사용해보기 (삽질 + Mesh) (0) | 2024.04.30 |
[책공부] 캐릭터 애니메이션 chap 23 (연습 문제 X) (0) | 2024.03.25 |
[책공부] Quaternion + chap 22 연습 문제 (0) | 2024.03.12 |
[책공부] Ambient Occlusion + chap 21 연습 문제 (0) | 2024.03.08 |