<p>That's how I used to initialize viewport (CD3DX12_VIEWPORT). But I didn't realize that there are two additional fields <em>minDepth</em> and <em>maxDepth</em>. Therefore, I have min/max depth set to 0.0 and objects rendered to depth buffer are always black:</p>
<pre><code>m_viewport.TopLeftY = 0.0f;
m_viewport.TopLeftX = 0.0f;
m_viewport.Width = static_cast&lt;float&gt;(m_windowSize.x);
m_viewport.Height = static_cast&lt;float&gt;(m_windowSize.y);
</code></pre>
<p>Fixed that by simply using constructor which default <em>minDepth</em> to 0.0 and <em>maxDepth</em> to 1.0:</p>
<pre><code>m_viewport = CD3DX12_VIEWPORT{ 0.0f, 0.0f, static_cast&lt;float&gt;(m_windowSize.x), static_cast&lt;float&gt;(m_windowSize.y) };
</code></pre>

CC BY-SA 4.0
2021-03-31T19:25:32.110Z
2021-03-31T19:25:32.110Z
DirectX_Programmer
<p>My problem is exactly what titles and screenshot below says - rendered object depth value is 0.0 in depth buffer. I'm using DirectX 12.</p>
<p><a href="https://i.sstatic.net/jTTnm.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/jTTnm.png" alt="enter image description here" /></a></p>
<p>Matrices:</p>
<p><a href="https://i.sstatic.net/Gcfrh.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/Gcfrh.png" alt="enter image description here" /></a></p>
<pre><code>// VS code
PixelInputType main(VertexInputType input)
{
    PixelInputType output;
    
    float4 position = float4(input.position, 1.0f);
    position = mul(position, g_worldMatrix);
    position = mul(position, g_viewMatrix);
    position = mul(position, g_projMatrix);
    output.position = position;

    return output;
}
// PS code
float4 main(PixelInputType input) : SV_TARGET
{
    return float4(g_texture.Sample(g_sampler, input.uv).rgb, 1.0f);
}
</code></pre>
<p>I am rendering single object for now, so world matrix is just identity matrix.
Regarding view/proj matrix - they're updated each frame and saved to the CB:</p>
<pre><code>void Renderer::CreateViewAndPerspective()
{
    const DirectX::XMVECTOR up = DirectX::XMVectorSet(0.0f, 1.0f, 0.0f, 0.f);
    constexpr float conv{ 0.0174532925f };

    // Create the rotation matrix from the yaw, pitch, and roll values.
    const XMMATRIX rotationMatrix = XMMatrixRotationRollPitchYaw(m_cameraRotation.x * conv, m_cameraRotation.y * conv, m_cameraRotation.z * conv);

    const DirectX::XMVECTOR eye = DirectX::XMVectorSet(m_cameraPosition.x, m_cameraPosition.y, m_cameraPosition.z, 0.0f);

    //Setup target (look at object position)
    XMVECTOR target = XMVector3TransformCoord(DirectX::XMVECTOR{ 0, 0, 1, 0 }, rotationMatrix);
    target = XMVector3Normalize(target);
    target = { m_cameraPosition.x + target.m128_f32[0], m_cameraPosition.y + target.m128_f32[1], m_cameraPosition.z + target.m128_f32[2], 0.0f };  

    //Create view matrix
    m_constantBuffer.value.view = DirectX::XMMatrixTranspose(DirectX::XMMatrixLookAtLH(eye, target, up));

    //Create perspective matrix
    constexpr float FOV = 3.14f / 4.0f;
    float aspectRatio = m_windowSize.x / m_windowSize.y /* 1280 x 720 */;
    m_constantBuffer.value.projection = DirectX::XMMatrixTranspose(DirectX::XMMatrixPerspectiveFovLH(FOV, aspectRatio, Z_NEAR /* 0.5f */, Z_FAR /* 100.0f */));
}
</code></pre>
<hr />
<p>Edit: Depth buffer implementation details below (full code - <a href="https://github.com/komilll/YARE/blob/main/YARE/Renderer.cpp#L131" rel="nofollow noreferrer">https://github.com/komilll/YARE/blob/main/YARE/Renderer.cpp#L131</a> ):</p>
<pre><code>// Create DSV
D3D12_DESCRIPTOR_HEAP_DESC desc{};
desc.NumDescriptors = 1;
desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_DSV;
desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
device-&gt;CreateDescriptorHeap(&amp;desc, IID_PPV_ARGS(&amp;heap));

// Create Depth Stencil
D3D12_DEPTH_STENCIL_VIEW_DESC depthStencilDesc = {};
depthStencilDesc.Format = DXGI_FORMAT_D32_FLOAT;
depthStencilDesc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2D;
depthStencilDesc.Flags = D3D12_DSV_FLAG_NONE;

D3D12_CLEAR_VALUE depthOptimizedClearValue = {};
depthOptimizedClearValue.Format = DXGI_FORMAT_D32_FLOAT;
depthOptimizedClearValue.DepthStencil.Depth = 1.0f;
depthOptimizedClearValue.DepthStencil.Stencil = 0;

ThrowIfFailed(device-&gt;CreateCommittedResource(
    &amp;CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT),
    D3D12_HEAP_FLAG_NONE,
    &amp;CD3DX12_RESOURCE_DESC::Tex2D(format, width, height, 1, 0, 1, 0, D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL),
    D3D12_RESOURCE_STATE_DEPTH_WRITE,
    &amp;depthOptimizedClearValue,
    IID_PPV_ARGS(&amp;depthStencil)
));

device-&gt;CreateDepthStencilView(depthStencil.Get(), &amp;depthStencilDesc, dsvHeap-&gt;GetCPUDescriptorHandleForHeapStart());

/* ... */
// Usage of DSV
const float clearColor[] = { 0.0f, 0.2f, 0.4f, 1.0f };
m_commandList-&gt;ClearRenderTargetView(rtvHandle, clearColor, 0, nullptr);
m_commandList-&gt;ClearDepthStencilView(m_dsvHeap-&gt;GetCPUDescriptorHandleForHeapStart(), D3D12_CLEAR_FLAG_DEPTH, 1.0f, 0, 0, nullptr);
m_commandList-&gt;IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
m_commandList-&gt;IASetVertexBuffers(0, 1, &amp;m_modelSphere-&gt;GetVertexBufferView());
m_commandList-&gt;DrawInstanced(m_modelSphere-&gt;GetIndicesCount(), 1, 0, 0);
</code></pre>

CC BY-SA 4.0
2021-03-27T00:37:57.680Z
Usually when the depth buffer is completely blank the issue is in the setup. Such as the clear clear, depth compare op, or framebuffer/attachment setup have an issue.
pmw1234
CC BY-SA 4.0
2021-03-27T09:44:45.857Z
@pmw1234 In this case, it's not fully blank. As you can see, clear value is correct and object is being drawn to depth/stencil buffer. The problem here is that its value in depth buffer is always 0.0.

I've added code of depth buffer creation to the main post.
DirectX_Programmer
CC BY-SA 4.0
2021-03-28T12:54:51.690Z
If depth clamping is enabled and the object is in front of the near plane, then the gpu will still draw the object and all the depths will be clamped to zero (instead of the negative values that they were after applying the MVP matrix).
pmw1234
CC BY-SA 4.0
2021-03-28T18:22:23.503Z
And how can I fix this? I mean, why would there be negative values in my depth buffer?
DirectX_Programmer
CC BY-SA 4.0
2021-04-01T12:39:23.823Z
Here is more info on depth clamping. I know this wasn't the issue in your code, but it does address your question, I believe Nicola Bolas is the author of the tutorial in this link. In direct X it is called depth clipping if I remember correctly: https://paroj.github.io/gltut/Positioning/Tut05%20Depth%20Clamping.html
pmw1234
CC BY-SA 4.0
2021-04-02T10:14:09.550Z
@pmw1234 Thank you for this link. Do you by any chance have any resources about creating Hi-Z buffer in DX12?
DirectX_Programmer
<directx12><camera-matrix><z-buffer>
Objects in depth buffer are always black (0.0)
DirectX_Programmer
# Objects in depth buffer are always black (0.0)

(Asked by: username_0 on 2021-03-26)

My problem is exactly what titles and screenshot below says - rendered object depth value is 0.0 in depth buffer. I'm using DirectX 12.

[![enter image description here](https://i.sstatic.net/jTTnm.png)](https://i.sstatic.net/jTTnm.png)

Matrices:

[![enter image description here](https://i.sstatic.net/Gcfrh.png)](https://i.sstatic.net/Gcfrh.png)

```
// VS code
PixelInputType main(VertexInputType input)
{
    PixelInputType output;
    
    float4 position = float4(input.position, 1.0f);
    position = mul(position, g_worldMatrix);
    position = mul(position, g_viewMatrix);
    position = mul(position, g_projMatrix);
    output.position = position;

    return output;
}
// PS code
float4 main(PixelInputType input) : SV_TARGET
{
    return float4(g_texture.Sample(g_sampler, input.uv).rgb, 1.0f);
}

```

I am rendering single object for now, so world matrix is just identity matrix.
Regarding view/proj matrix - they're updated each frame and saved to the CB:

```
void Renderer::CreateViewAndPerspective()
{
    const DirectX::XMVECTOR up = DirectX::XMVectorSet(0.0f, 1.0f, 0.0f, 0.f);
    constexpr float conv{ 0.0174532925f };

    // Create the rotation matrix from the yaw, pitch, and roll values.
    const XMMATRIX rotationMatrix = XMMatrixRotationRollPitchYaw(m_cameraRotation.x * conv, m_cameraRotation.y * conv, m_cameraRotation.z * conv);

    const DirectX::XMVECTOR eye = DirectX::XMVectorSet(m_cameraPosition.x, m_cameraPosition.y, m_cameraPosition.z, 0.0f);

    //Setup target (look at object position)
    XMVECTOR target = XMVector3TransformCoord(DirectX::XMVECTOR{ 0, 0, 1, 0 }, rotationMatrix);
    target = XMVector3Normalize(target);
    target = { m_cameraPosition.x + target.m128_f32[0], m_cameraPosition.y + target.m128_f32[1], m_cameraPosition.z + target.m128_f32[2], 0.0f };  

    //Create view matrix
    m_constantBuffer.value.view = DirectX::XMMatrixTranspose(DirectX::XMMatrixLookAtLH(eye, target, up));

    //Create perspective matrix
    constexpr float FOV = 3.14f / 4.0f;
    float aspectRatio = m_windowSize.x / m_windowSize.y /* 1280 x 720 */;
    m_constantBuffer.value.projection = DirectX::XMMatrixTranspose(DirectX::XMMatrixPerspectiveFovLH(FOV, aspectRatio, Z_NEAR /* 0.5f */, Z_FAR /* 100.0f */));
}

```

---

Edit: Depth buffer implementation details below (full code - <https://github.com/komilll/YARE/blob/main/YARE/Renderer.cpp#L131> ):

```
// Create DSV
D3D12_DESCRIPTOR_HEAP_DESC desc{};
desc.NumDescriptors = 1;
desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_DSV;
desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
device->CreateDescriptorHeap(&desc, IID_PPV_ARGS(&heap));

// Create Depth Stencil
D3D12_DEPTH_STENCIL_VIEW_DESC depthStencilDesc = {};
depthStencilDesc.Format = DXGI_FORMAT_D32_FLOAT;
depthStencilDesc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2D;
depthStencilDesc.Flags = D3D12_DSV_FLAG_NONE;

D3D12_CLEAR_VALUE depthOptimizedClearValue = {};
depthOptimizedClearValue.Format = DXGI_FORMAT_D32_FLOAT;
depthOptimizedClearValue.DepthStencil.Depth = 1.0f;
depthOptimizedClearValue.DepthStencil.Stencil = 0;

ThrowIfFailed(device->CreateCommittedResource(
    &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT),
    D3D12_HEAP_FLAG_NONE,
    &CD3DX12_RESOURCE_DESC::Tex2D(format, width, height, 1, 0, 1, 0, D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL),
    D3D12_RESOURCE_STATE_DEPTH_WRITE,
    &depthOptimizedClearValue,
    IID_PPV_ARGS(&depthStencil)
));

device->CreateDepthStencilView(depthStencil.Get(), &depthStencilDesc, dsvHeap->GetCPUDescriptorHandleForHeapStart());

/* ... */
// Usage of DSV
const float clearColor[] = { 0.0f, 0.2f, 0.4f, 1.0f };
m_commandList->ClearRenderTargetView(rtvHandle, clearColor, 0, nullptr);
m_commandList->ClearDepthStencilView(m_dsvHeap->GetCPUDescriptorHandleForHeapStart(), D3D12_CLEAR_FLAG_DEPTH, 1.0f, 0, 0, nullptr);
m_commandList->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
m_commandList->IASetVertexBuffers(0, 1, &m_modelSphere->GetVertexBufferView());
m_commandList->DrawInstanced(m_modelSphere->GetIndicesCount(), 1, 0, 0);

```

**Tags:** directx12, camera-matrix, z-buffer

> **Comments:**
> **username_1**: Usually when the depth buffer is completely blank the issue is in the setup. Such as the clear clear, depth compare op, or framebuffer/attachment setup have an issue.  
> **username_0**: @username_1 In this case, it's not fully blank. As you can see, clear value is correct and object is being drawn to depth/stencil buffer. The problem here is that its value in depth buffer is always 0.0.  I've added code of depth buffer creation to the main post.  
> **username_1**: If depth clamping is enabled and the object is in front of the near plane, then the gpu will still draw the object and all the depths will be clamped to zero (instead of the negative values that they were after applying the MVP matrix).  
> **username_0**: And how can I fix this? I mean, why would there be negative values in my depth buffer?  
> **username_1**: Here is more info on depth clamping. I know this wasn't the issue in your code, but it does address your question, I believe Nicola Bolas is the author of the tutorial in this link. In direct X it is called depth clipping if I remember correctly: https://paroj.github.io/gltut/Positioning/Tut05%20Depth%20Clamping.html  
> **username_0**: @username_1 Thank you for this link. Do you by any chance have any resources about creating Hi-Z buffer in DX12?  

---

## 1 answers

### Answer by username_0 on 2021-03-31. Score: 2 | Accepted answer

That's how I used to initialize viewport (CD3DX12\_VIEWPORT). But I didn't realize that there are two additional fields *minDepth* and *maxDepth*. Therefore, I have min/max depth set to 0.0 and objects rendered to depth buffer are always black:

```
m_viewport.TopLeftY = 0.0f;
m_viewport.TopLeftX = 0.0f;
m_viewport.Width = static_cast<float>(m_windowSize.x);
m_viewport.Height = static_cast<float>(m_windowSize.y);

```

Fixed that by simply using constructor which default *minDepth* to 0.0 and *maxDepth* to 1.0:

```
m_viewport = CD3DX12_VIEWPORT{ 0.0f, 0.0f, static_cast<float>(m_windowSize.x), static_cast<float>(m_windowSize.y) };

```


---

