1
$\begingroup$

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

Matrices:

enter image description here

// 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);
$\endgroup$
6
  • $\begingroup$ 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. $\endgroup$
    – pmw1234
    Commented Mar 27, 2021 at 0:37
  • $\begingroup$ @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. $\endgroup$ Commented Mar 27, 2021 at 9:44
  • $\begingroup$ 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). $\endgroup$
    – pmw1234
    Commented Mar 28, 2021 at 12:54
  • $\begingroup$ And how can I fix this? I mean, why would there be negative values in my depth buffer? $\endgroup$ Commented Mar 28, 2021 at 18:22
  • 1
    $\begingroup$ 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: paroj.github.io/gltut/Positioning/Tut05%20Depth%20Clamping.html $\endgroup$
    – pmw1234
    Commented Apr 1, 2021 at 12:39

1 Answer 1

2
$\begingroup$

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) };
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.