You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/1-introduction/1-3-basics/1-3-4-3d-rendering.md
+83-5Lines changed: 83 additions & 5 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -17,11 +17,89 @@ This depth buffer can then be used by special hardware on the GPU to see if the
17
17
18
18
This is called "Depth Testing", a very important concept within common rendering.
19
19
20
-
!!! error
21
-
add depth buffer + state
20
+
So let's create our depth buffer which in D3D11 are called a `DepthStencil` and the handle for it being a `DepthStencilView` (a "DSV" as we'll call em from here on)
22
21
23
-
!!! error
24
-
explain rasterizer desc -> DepthClipEnable (visually as well if possible)
22
+
In `CreateDepthStencilView()` we have the following code:
23
+
24
+
D3D11_TEXTURE2D_DESC texDesc{};
25
+
texDesc.Height = GetWindowHeight();
26
+
texDesc.Width = GetWindowWidth();
27
+
texDesc.ArraySize = 1;
28
+
texDesc.SampleDesc.Count = 1;
29
+
texDesc.MipLevels = 1;
30
+
texDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
31
+
texDesc.Format = DXGI_FORMAT_R32_TYPELESS;
32
+
33
+
ID3D11Texture2D* texture = nullptr;
34
+
if (FAILED(_device->CreateTexture2D(&texDesc, nullptr, &texture)))
35
+
{
36
+
std::cout << "DXGI: Failed to create texture for DepthStencilView\n";
std::cout << "DXGI: Failed to create DepthStencilView\n";
46
+
texture->Release();
47
+
return;
48
+
}
49
+
50
+
texture->Release();
51
+
52
+
Most of the setup for the DSV is very much the same as creating a texture, the only difference being the BindFlags and the Format.
53
+
BindFlags needs to be `D3D11_BIND_DEPTH_STENCIL` in order to let D3D11 know that we're going to bind it as a DSV,
54
+
the only curious thing here is `DXGI_FORMAT_R32_TYPELESS` because the internal format for depth (even though we view it as a FLOAT) is not really a raw buffer full of floats,
55
+
but a special format that can differ between GPUs, thankfully we don't need to be concerned with that and all we need to tell it is that it's "typeless".
56
+
57
+
Lastly in the `dsvDesc` we actually have two commonly usable choices:
58
+
59
+
- DXGI_FORMAT_D32_FLOAT (with `DXGI_FORMAT_R32_TYPELESS` on the texture)
60
+
- DXGI_FORMAT_D24_UNORM_S8_UINT (with `DXGI_FORMAT_R24G8_TYPELESS` on the texture)
61
+
62
+
The latter one will also reserve room for something called a "Stencil", which can be used for rendering techniques, we'll explain that one in a later chapter.
63
+
64
+
One important thing we need to mention is that the DSV always needs to match in resolution with the bound RenderTargetView, so in our case we need to also make sure to resize it if we resize the window.
65
+
However because there is no functionality to "resize" a DSV, the solution is to clean up our current one and create a new one with the matching resolution.
66
+
67
+
In order to use this newly created DSV we need to set it using the last parameter in `ID3D11DeviceContext::OMSetRenderTargets()`
Note that this takes a `D3D11_CLEAR_FLAG` and two more arguments, the `D3D11_CLEAR_FLAG` allows us to clear Depth and Stencil seperately or both at once by OR-ing them together.
76
+
The final two arguments are the values to clear the DSV to, first the depth value and lastly the stencil value.
77
+
78
+
## The Depth State
79
+
80
+
In order to actually use the DSV we just created we need to set up a `DepthStencilState`, the code for this is pretty simple, in `CreateDepthState()` we have the following:
`DepthEnable` is exactly what it sounds like, it "enables" the usage of the DSV.
90
+
`DepthFunc` is what allows us to get Depth Testing, `D3D11_COMPARISON_LESS` tells it to only draw fragments that have a depth "lesser" than the current value (things that are in front of the current fragment)
91
+
`DepthWriteMask` is what allows us to specify whether we should write to the DSV or not, we can only specify ALL or ZERO (which disables writing).
92
+
93
+
Finally all we need to do is set it by calling `ID3D11DeviceContext::OMSetDepthStencilState()`
And.. That's it! Running the application now will cause the cube to show up all proper-like!
98
+
99
+

100
+
101
+
This is because it now uses depth to make sure whether the fragment we're drawing is actually in front of older ones, so we're no longer reliant on the order of the vertices we're drawing, which if we would, would make 3D rendering a 'lot' harder as we'd need to sort all polygons in depth every frame we move the camera around.
102
+
103
+
From here on out you should be able to create your own renderer using all the knowledge you have received so far, as an extra the next chapters will show you how to load models and get some very nice debugging UI going!
0 commit comments