1

I'm really new to graphics programming in general, so please bear with me. I am trying to add shadow mapping from a distant light (orthogonal projection) into my scene, but when I follow the (very incomplete) steps from Frank Luna's DX12 book I find that my SRV for the shadow map is just filled with depths of 1.

If it helps, here is my SRV definition:

D3D12_TEX2D_SRV texDesc = {
        0,
        -1,
        0,
        0.0f
    };
    D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc = {
        DXGI_FORMAT_R32_TYPELESS,
        D3D12_SRV_DIMENSION_TEXTURE2D,
        D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING,
    };
    srvDesc.Texture2D = texDesc;

    m_device->CreateShaderResourceView(m_lightDepthTexture.Get(),&srvDesc, m_cbvHeap->GetCPUDescriptorHandleForHeapStart());

and here are my DSV heap and descriptor definitions:

D3D12_DESCRIPTOR_HEAP_DESC dsvHeapDesc = {};
    dsvHeapDesc.NumDescriptors = 2;
    dsvHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_DSV;
    dsvHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
    ThrowIfFailed(m_device->CreateDescriptorHeap(&dsvHeapDesc, IID_PPV_ARGS(&m_dsvHeap)));

    D3D12_DEPTH_STENCIL_VIEW_DESC depthStencilDesc = {};
    depthStencilDesc.Format = DXGI_FORMAT_D32_FLOAT;
    depthStencilDesc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2D;
    depthStencilDesc.Flags = D3D12_DSV_FLAG_NONE;

    CD3DX12_HEAP_PROPERTIES heapProps = CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT);
    CD3DX12_RESOURCE_DESC resourceDesc = CD3DX12_RESOURCE_DESC::Tex2D(DXGI_FORMAT_R32_TYPELESS, m_width, m_height, 1, 0, 1, 0, D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL);

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

    ThrowIfFailed(m_device->CreateCommittedResource(
        &heapProps,
        D3D12_HEAP_FLAG_NONE,
        &resourceDesc,
        D3D12_RESOURCE_STATE_DEPTH_WRITE,
        &depthOptimizedClearValue,
        IID_PPV_ARGS(&m_dsvBuffer)
    ));

    D3D12_RESOURCE_DESC texDesc;
    ZeroMemory(&texDesc, sizeof(D3D12_RESOURCE_DESC));
    texDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
    texDesc.Alignment = 0;
    texDesc.Width = m_width;
    texDesc.Height = m_height;
    texDesc.DepthOrArraySize = 1;
    texDesc.MipLevels = 1;
    texDesc.Format = DXGI_FORMAT_R32_TYPELESS;
    texDesc.SampleDesc.Count = 1;
    texDesc.SampleDesc.Quality = 0;
    texDesc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
    texDesc.Flags = D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL;

    ThrowIfFailed(m_device->CreateCommittedResource(
        &heapProps,
        D3D12_HEAP_FLAG_NONE,
        &texDesc,
        D3D12_RESOURCE_STATE_GENERIC_READ,
        &depthOptimizedClearValue,
        IID_PPV_ARGS(&m_lightDepthTexture)
    ));


    CD3DX12_CPU_DESCRIPTOR_HANDLE dsv(m_dsvHeap->GetCPUDescriptorHandleForHeapStart());
    m_device->CreateDepthStencilView(m_dsvBuffer.Get(), &depthStencilDesc, dsv);
    dsv.Offset(1, m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_DSV));

    m_device->CreateDepthStencilView(m_lightDepthTexture.Get(), &depthStencilDesc, dsv);

I then created a basic vertex shader that just transforms the vertices with my map (from Frank Luna's book, page 648,650). Since I bound the m_lightDepthTexture to D3D12GraphicsCommandList::OMSetRenderTargets, I assumed that the depth values would be written onto m_lightDepthTexture. But simply sampling this texture in my main pass proves that the values are actually 1.0f. So nothing actually happened on my shadow pass!

I really have no idea what to ask, but if anyone has a sample DX12 shadow map I could see (Google comes up with DX11 or less, or much too complicated samples), or if there's a good source to learn about this, please let me know!

EDIT: I should say that I changed the format from DXGI_FORMAT_D24_UNORM_S8_UINT, as I think the extra 8 bits for stencil is irrelevant to my case. I changed back to the book format and nothing changed, so I think this format should be fine.

user722227
  • 113
  • 5
  • 1
    Can you try putting your format for SRV to DXGI_FORMAT_R32_FLOAT and not DXGI_FORMAT_R32_TYPELESS? Have you enabled debug layer? (If you don't know you can find it easily) – mateeeeeee Oct 20 '22 at 18:57
  • I tried this earlier, but I get an error that the format must match that of the clear value. I have also enabled the debug layer. – user722227 Oct 21 '22 at 01:37
  • I also adopted Luna's shadow map class in my game without issue. Agree with @mateeeeeee that srvDesc.Format cannot be _R32_TYPELESS. If _R32_FLOAT didn't work, try `DXGI_FORMAT_R24_UNORM_X8_TYPELESS`. – Maico De Blasio Oct 21 '22 at 02:15
  • Thanks for the reply. Unfortunately this change doesn't change my output at all. I found that it is possible to alter the texture, which I found by setting the return position of my shadow VS to 0.0f. This caused half of my texture to be 0 and the other half to be 1. For some reason this is the only change I could make that affected my resource. – user722227 Oct 21 '22 at 02:54
  • You are doing something fundamentally different to Luna's example in the book, which renders correctly. I suggest a line by line comparison of the code to identify where you have deviated.. it's usually the best way to debug what's going wrong. – Maico De Blasio Oct 21 '22 at 06:19
  • You have the code repository somewhere public? – mateeeeeee Oct 21 '22 at 07:32
  • @mateeeeeee I just created one: https://github.com/hlembeck/DX12-Test-Bench. I messed with some sampler settings here, and I also messed with the transforms to try and alter the result. Now I find that the comparison function doesn't work (compare always gives one extreme, compare never gives other extreme, and compare less_equal goes to one of those extremes... despite having the comparison value strictly between 0 and 1). I'll look at that more later. – user722227 Oct 21 '22 at 21:38
  • @MaicoDeBlasio I'm not entirely sure where to find Luna's actual code, as he only provides snippets (in the version I have). I've been jumping around that book, so my code is unlikely to have the same structure as his. That said, I reformatted my shadow map code to something similar to his, and this is in my github repository (linked above). – user722227 Oct 21 '22 at 21:41
  • 1
    The source for Luna's DX12 book is [here](https://github.com/d3dcoder/d3d12book) – Maico De Blasio Oct 22 '22 at 02:22

1 Answers1

2

If you remove the unecessary return ret; from your shadow vertex shader, the problem then seems to be in winding order of vertices of your sphere. You can easily verify this by setting cull mode to D3D12_CULL_MODE_NONE for your shadow PSO.

You can easily correct your sphere winding order by switching order of any two vertices of every triangle, so wherever you have p1,p2,p3 you just write it for example as p1,p3,p2.

You will also need to check your matrix multiplication order in your vertex shaders, I didn't checked it in detail but it's inconsistent and I believe the cause why the sphere will appear black when you fix the above issue. You also seem to be missing division by w for your light coords in lighting vertex shader.

mateeeeeee
  • 885
  • 1
  • 6
  • 15
  • Ah, that ret definitely was an issue, oops! Thank you! I was messing with this thing so much that I changed pretty much all the relevant code in the shaders to alter stuff. I think the winding order is correct, but the order of multiplication could have prevented the correct computation. – user722227 Oct 22 '22 at 02:37