DirectX 12 + DXR 기반 게임 엔진과 에디터. DX11 엔진(DX11, 비공개)을 전신으로 두고 DX12/레이트레이싱으로 다시 설계·이식한 프로젝트입니다. C++20 / HLSL SM6.5 / Visual Studio 2022.
![]() |
![]() |
| 역분석한 원본 NPR 모델로 렌더한 캐릭터 (램버트 + 스페큘러 LUT + 폭 마스크 아웃라인) | 눈 3장 텍스처 합성 / 손그림 알베도 / 애니 노멀 평탄화 |
![]() |
![]() |
| 머리카락 이방성 하이라이트, 스킨드 BLAS refit 위 RT 그림자 | 도킹 에디터: 계층 / 인스펙터 / 프로젝트 / 로그 / 플레이 모드 |
궤도 카메라 + 색상 변형(알베도 텍스처 교체) 순환 → 공격 콤보 → 플레이 모드 전투(적 AI 추격/협공, 팔로우 카메라). 36초, 엔진 내장 프레임 덤프를 tools/make_video.py 로 인코딩 — MP4 원본
![]() |
![]() |
| 26만 삼각형 / 머티리얼 25종. 태양광이 중정으로 들어오고 나머지는 전부 DDGI 간접광 | 2층 회랑 — RT 그림자 + RT AO (섀도맵 없음) |
같은 프레임에서 GI 만 끈 비교 — 평균 휘도 72 → 113. 아케이드 안쪽은 프로브 간접광이 전부다.
36초 플라이스루, 1080p60(MP4) — 지상 회랑 → 2층 → 태양 이동 → DDGI OFF/ON.
3870x2160 으로 렌더해 1080p 로 내리는 2x 슈퍼샘플 캡처.
EngineDX12.exe --demo tools\demo_sponza.txt 로 프레임을 덤프하고 tools/make_video.py 로 인코딩한, 사람 손 안 타는 재현 가능한 컷.
Sponza 에셋은 저작권 문제로 저장소에 넣지 않는다.
python tools/fetch_sponza.py가 Khronos 샘플(glTF)을 받아 Blender 로 FBX 로 바꾸고 엔진 컨버터(--convert-fbx)까지 돌려.mesh/.mmat를 만들어 준다.
📝 기술 노트: 상용 게임 NPR 셰이더 역분석 · DDGI 블룸 폭발 추적기
| 영역 | 내용 |
|---|---|
| 렌더링 | DXR 1.1 인라인 레이트레이싱 (RayQuery) 그림자·AO·반사, DDGI 프로브 GI(SH-L1, 옥타헤드럴 depth, 다중 바운스), IBL(큐브맵 → SH 베이크), HDR + ACES 톤맵, TAA, 블룸/DOF/볼류메트릭 |
| 캐릭터 | GPU 컴퓨트 스키닝, 정적 모델 공유 BLAS / 스킨드 BLAS refit, 애니메이션 상태머신 + 크로스페이드 + 노티파이, 본 부착(소켓/추종 2모드), 애니 시간 동기화 |
| NPR 파이프라인 | 상용 게임(그랑블루 판타지 리링크)의 캐릭터 셰이더를 DXBC 디스어셈블로 역분석해 재현 — 램버트 + shadowMin, acos(N·H) 인덱싱 스페큘러 성형 LUT, 애니 노멀 평탄화, 파츠별 앰비언트, 정점별 폭 마스크 인버티드 헐 아웃라인, 눈 3장 텍스처 합성 |
| 머티리얼 | 서브메시 슬롯별 PBR/툰 파라미터, JSON 프리셋 일괄 적용/저장, 색상 변형(알베도 텍스처 교체 + 변형별 모델 캐시) |
| 에디터 | ImGui 도킹, ImGuizmo 기즈모, 계층/인스펙터/프로젝트/로그 창, 씬 직렬화, 플레이 모드(스냅샷/복원), 게임 카메라 프리뷰, 터레인 스컬프트/페인트, 포리지 |
| 에셋 | ufbx 기반 FBX → .mesh/.clip/.mmat 컨버터, 텍스처 사이드카 오버라이드, 썸네일 |
| 게임플레이 | MonoBehaviour 스크립트(직렬화 레지스트리), 3인칭 플레이어/적 AI/팔로우 카메라, HUD |
DX12Engine.sln열기 → x64 Debug/Release → 빌드 (EngineDX12 단일 프로젝트)- 실행 파일:
Binaries\EngineDX12.exe(셰이더는 빌드 후Binaries\Shaders\로 복사되어 런타임 DXC 컴파일) - 요구 사항: Windows 10 20H2+ / DXR 1.1 지원 GPU (RTX 20xx 이상 또는 RDNA2 이상) / Windows SDK 10.0
서드파티는 전부 ThirdParty/ 에 동봉: Dear ImGui(docking) · ImGuizmo · ufbx · DirectXTex — 모두 MIT.
스모크 테스트: powershell -ExecutionPolicy Bypass -File tools\verify.ps1 (실행 → 백그라운드 캡처 → _verify.png)
그래픽스 버그는 로그에 안 찍힌다. 그래서 기능을 붙일 때마다 엔진을 실제로 띄워 화면을 캡처하고 그 이미지를 보고 판단하는 루프를 고정했다:
tools\verify.ps1— exe 실행 → 창을 Z 최하단에 두고 포커스는 원래 창에 돌려준 채 PrintWindow 로 캡처 (작업 중인 다른 창을 방해하지 않음)- 엔진 내장 2x 백버퍼 리드백 스크린샷(
File > Screenshot Hi-Res) — 에디터 UI 없는 렌더 결과만 EngineDX12.exe --demo <script>(DemoCapture.cpp) — 씬 로드 / 룩 파라미터 / 카메라 키프레임 / 시간축 토글을 텍스트로 적어 두고 재생하며 프레임을 덤프. 사람 입력 없이 재현 가능한 컷이라 파라미터만 바꿔 언제든 다시 찍는다 (tools/demo_sponza.txt가 위 Sponza 영상의 스크립트)
이 루프로 잡은 것들: 본 부착 0.6m 오차, 스크린샷 PNG 채널 반전(WIC 인코더가 RGBA 요청을 BGRA 로 바꿈),
변형 전환 후 눈이 흰자만 나오던 문제(프리셋 미적용), 샘플러 가시성 PIXEL 로 인한 PSO 생성 실패(창 없이 행),
Sponza 를 넣고 나서야 드러난 것들 — 텍스처를 밉 없이 올려서 생긴 원거리 모아레, 한 노드에 머티리얼이 여럿인 FBX 가
첫 머티리얼로 뭉치던 컨버터, 6샘플 RT AO 의 삼각형 밴딩 등.
media/ 의 스크린샷도 전부 이 경로로 뽑았다.
EngineDX12/
D3D12Device.* 디바이스/스왑체인/루트시그니처/PSO, 텍스처 업로드
D3D12Render.cpp 프레임 루프: AS 빌드 → 스키닝 → 불투명/아웃라인/투명 → 포스트
D3D12Passes.cpp 터레인 테셀레이션, 물, 빌보드 파티클
Ddgi.* DDGI 프로브 볼륨 (레이 디스패치, SH 누적, depth 옥타헤드럴)
PostFX.* HDR 체인 (TAA/블룸/DOF/톤맵/렌즈)
ModelAnimator.* 스킨드 모델: 로드/캐시, GPU 스키닝, 상태머신, 머티리얼 슬롯·프리셋
MeshRenderer/ModelRenderer/Foliage/Terrain/ParticleSystem
Scene/GameObject/Transform/Component/MonoBehaviour 씬 그래프
Scripts.h 게임 스크립트 (PlayerController, EnemyController, BoneAttachment, AnimSync, FollowCamera)
D3D12Editor/Inspector/Serialize/Spawn.cpp 에디터 UI, .rtscene 직렬화
DemoCapture.cpp --demo 스크립트 재생(카메라 경로/룩/토글) → 프레임 시퀀스 덤프
Shaders/ Mesh.hlsl (메인 포워드+RT), Outline, Sky, Skinning(CS), Gather(DDGI), PostFX...
ThirdParty/ imgui, ufbx, DirectXTex (헤더+lib)
Resources/Assets/ 샘플 에셋 (Mixamo 캐릭터, 텍스처, 씬)
tools/ 검증 스모크 테스트, 데모 캡처 스크립트, Sponza 에셋 파이프라인, 영상 인코더
docs/ 기술 노트
- 01 · 상용 게임 NPR 셰이더 역분석 — "추측(램프 확산)" 이 틀렸음을 DXBC 로 확인하고 원본 모델로 재현하기까지
- 02 · DDGI 시간 경과 블룸 폭발 — 다중 바운스 루프 게인 > 1 (빠진 /π) 추적과 수렴 보장
- (예정) 본 부착 0.6m 오차 — 합성 행렬에서 스케일을 지우면 정규화 스케일까지 사라진다
- (예정) DX12 루트 시그니처/디스크립터 힙 설계 — 드로우당 힙 전환 제거, 공유 SRV 힙, 루트상수 per-object 머티리얼
- 캐릭터(Archer/Kachujin/Mutant): Mixamo 무료 에셋
- Sponza: glTF Sample Assets (Crytek Sponza, Frank Meinl — CC BY 4.0).
저장소에는 미포함 —
tools/fetch_sponza.py로 받는다. - 리링크 캐릭터를 이용한 NPR 데모는 영상/스크린샷으로만 제공합니다. 게임에서 추출한 에셋은 저작권 문제로 저장소에 포함하지 않으며, 엔진은 해당 파일이 없어도 동작합니다 (흰색 폴백).








