Github Link: https://github.com/SquallLiu99/Squall-D3D12-Demo
Full Project & Executable File link are on the bottom of this article.
Custom demo of D3D12 Rendering.
It's not the best but it's how I try to maximize the advantage of D3D12.
I borrow the Unity's asset system to get all resources as ID3D12Resource interface, and customize my renderer in native DLL.
I also implement some material management(PSO) and shader parser.
Requirement to run the demo
- Unity Editor 2018.4.17f1+ (or running the executable file instead of installing editor)
- Win10 for running D3D12. With version 1909 + 2004 SDK.
(Maybe you can try a lower version with 2004 SDK installed, I just enumerate my developing environment here.)
- Developer Mode Enabled. Measuring GPU time needs it.
Here is the document that shows you how to enable developer mode:
https://docs.microsoft.com/en-us/windows/apps/get-started/enable-your-device-for-development
- NVIDIA RTX Graphic Cards
Yes, I implement the DXR ray tracing shader and don't consider fallback API for GTX series.
(Since GTX series are impossible to get real time performance.)
You can try AMD RX cards also, but I'm not sure since I don't have one.
Missing one of above requirement the demo would crash.
My testing rig is R5 3600X + RTX 2070.
Features
Multithread Forward+ Rendering
Fig 1. Multithread Rendering
Fig 2. Can choose number of threads to render.
This is the key design of D3D12, Microsoft wants us to submit work on different threads.
As it shown in image, I use AMD R5 5600X (6C12T) to run the test. I set 12 threads to rendering.
Now the total draw calls in this shot is 377, which means each thread renders about 31 draw calls.
You can specify the number of threads in my system, max up to min(16, MaxLogicialCpuCore). Only Works on initialization.
Fig3. My rendering pipeline
My rendering pipeline, the work with a star mark means I use multithread on it.
Instance Based Rendering
In demo scene, there are 2XXX draw calls at the beginning.
I collect the objects that has the same mesh/material, and implement the instance based rendering. And now total draw calls in the scene are less than 400.
SM5.1 Style Texture Management
D3D12 introduce the concept of Descriptor Heap. (https://docs.microsoft.com/en-us/windows/win32/direct3d12/descriptor-heaps)
I collect all ShaderResourceView into a big texture descriptor heap.
My texture sampling is gonna like this:
// need /enable_unbounded_descriptor_tables when compiling Texture2D _SqTexTable[] : register(t0); SamplerState _SqSamplerTable[] : register(s0); #define SQ_SAMPLE_TEXTURE(x,y,z) _SqTexTable[x].Sample(_SqSamplerTable[y], z) float4 color = SQ_SAMPLE_TEXTURE(_DiffuseTexIndex, _LinearSamplerIndex);
Shader model 5.1 provides dynamic indexing and we can have more flexible way for texture binding.
Tiled-Based Light Culling
So that my forward rendering becomes forward+ rendering!
I apply the tiled-based light culling on point lights.
Currently my implementation doesn't contain spot light, since it is strange to have spotlights on middle ages demo scene.
https://thegraphicguysquall.wordpress.com/2020/09/17/forward-light-culling/
Realtime Ray Tracing Shadows + PCSS
Directional light and point light ray tracing shadows with PCSS.
Both opaque/transparent can receive shadows. (However only the frontmost transparent object can receive shadows for performance.)
Test video:
https://www.youtube.com/watch?v=y1H-_5fZ0wI
Implement Detail:
https://thegraphicguysquall.wordpress.com/2020/08/14/squalls-graphic-dxr-ray-tracing-shadow/
https://thegraphicguysquall.wordpress.com/2020/08/24/ray-tracing-shadow-semi-pcss/
https://thegraphicguysquall.wordpress.com/2020/09/02/point-light-ray-tracing-shadow/
Realtime Ray Tracing Reflections
Realtime ray tracing reflection with FXAA applied. (FXAA is not in video but latest implementation.)
Recurrsive reflections are also supported, and I set the maximum recurrsive count to 3. I can also set recurrsive count for different materials.
Both opaque/transparent can receive reflections. However only the frontmost transparent object can receive reflections for performance.)
I also use smoothness threshold check for saving performance.
Test Video:
https://www.youtube.com/watch?v=1tcz-XE0tuI
Implement Detail:
https://thegraphicguysquall.wordpress.com/2020/10/13/squalls-graphic-custom-ray-tracing-reflection/
Realtime Ray Tracing Ambient Lighting
Realtime Ray Tracing Ambient Diffuse/Occlusion.
Currently apply and trace on opaque object only.
Test Video:
https://www.youtube.com/watch?v=8G5hXHF3DGg
Implement Detail:
https://thegraphicguysquall.wordpress.com/2020/11/05/squalls-graphic-custom-dxr-ray-tracing-ambient/
Final Words
This is just a part of D3D12.
I haven't learned other features like mesh shaders/VRS but I will!
It's always interesting to learn new things :D.
Unity Project Link: https://drive.google.com/file/d/1z6e8OazLlCByPLYQ75lICwP1vW71kVqw/view?usp=sharing
The folder Squall Graphics is Unity project.
And D3D Plugin Source is native implement project.
Executable File Link: https://drive.google.com/file/d/1tYJHLdzFgJvlKga8vBlYaq0OhZZx4xO7/view?usp=sharing
That's a great start! Tough work