shaderhlsldirectx-12shadow-mapping

why this shader variable doesn't change?(dx12, hlsl)


I'm working with dx12 and hlsl, and this specific root constant seems doesn't change or doesn't work for index.

this is hlsl code

#include "LightUtil.hlsli"

cbuffer cbCameraInfo : register(b1)
{
    matrix gmtxViewProj : packoffset(c0);
    float3 cameraPos : packoffset(c4);
    
    //size : 19
};

cbuffer cbLightInfo : register(b2)
{
    int nLights : packoffset(c0);
    int nShadowIndex : packoffset(c4); // - this is the constant
}

cbuffer cbShadowInfo : register(b3)
{
    matrix gmtxShadowTransform[3];
    matrix gmtxLightViewProj[3];
    matrix gmtxCascadedViewProj[3];
    float3 ShadowCameraPos;
}

Texture2D gShadowMap[3] : register(t0);
Texture2D gTextureMaps[6] : register(t3);

struct INSTANCED_GAMEOBJECT_INFO
{
    matrix m_mtxGameObject;
    int m_nTextrueIndex;
};
StructuredBuffer<INSTANCED_GAMEOBJECT_INFO> gGameObjectInfos : register(t0, space1);

StructuredBuffer<LIGHT_INFO> light : register(t1, space1);

SamplerState gsamPointWrap : register(s0);
SamplerState gsamPointClamp : register(s1);
SamplerState gsamLinearWrap : register(s2);
SamplerState gsamLinearClamp : register(s3);
SamplerState gsamAnisotropicWrap : register(s4);
SamplerState gsamAnisotropicClamp : register(s5);
SamplerComparisonState gsamShadow : register(s6);

and when I use nShadowIndex like this

#include "Common.hlsli"

struct VertexIn
{
    float3 PosL : POSITION;
};

struct VertexOut
{
    float4 PosH : SV_POSITION;
};

VertexOut VS(VertexIn vin)
{
    VertexOut vout = (VertexOut) 0.0f;
    
    // Transform to world space.
    float4 posW = mul(float4(vin.PosL, 1.0f), gmtxWorld);
    // Transform to homogeneous clip space.
    
    vout.PosH = mul(posW, gmtxLightViewProj[nShadowIndex]);
    
    return vout;
}

// This is only used for alpha cut out geometry, so that shadows 
// show up correctly.  Geometry that does not need to sample a
// texture can use a NULL pixel shader for depth pass.
void PS(VertexOut pin)
{
    // Fetch the material data.
    MATERIAL matData = material;
    float4 diffuseAlbedo = matData.DiffuseAlbedo;
}

this shader always returns same result because of nShadowIndex always fixed to 0.

and this is how i set variables. (there's many other vars, but not that important for this) as you see, what i'm trying to do is cascaded shadow map.

void CShadowShader::UpdateShaderVariables(ID3D12GraphicsCommandList* pd3dCommandList, XMFLOAT3 xmf3TargetPos, float fBoundary, int nShadowIndex)
{
    XMVECTOR lightPos = XMLoadFloat3(&m_pLight->GetPosition());
    XMVECTOR TargetPos = XMLoadFloat3(&xmf3TargetPos);
    XMVECTOR lightUp = XMLoadFloat3(&m_pLight->GetUp());

    XMVECTOR lightDir = XMVectorSubtract(lightPos, TargetPos);
    float lightLength = XMVector3Length(lightDir).m128_f32[0];

    XMMATRIX lightView = XMMatrixLookAtLH(lightPos, TargetPos, lightUp);

    // Transform bounding sphere to light space.
    XMFLOAT3 xmf3CenterLS;
    XMStoreFloat3(&xmf3CenterLS, XMVector3TransformCoord(XMLoadFloat3(&xmf3TargetPos), lightView));

    // Ortho frustum in light space encloses scene.
    float l = xmf3CenterLS.x - fBoundary;
    float b = xmf3CenterLS.y - fBoundary;
    float n = xmf3CenterLS.z - fBoundary;
    float r = xmf3CenterLS.x + fBoundary;
    float t = xmf3CenterLS.y + fBoundary;
    float f = xmf3CenterLS.z + fBoundary;

    XMMATRIX lightProj;
    lightProj = XMMatrixOrthographicOffCenterLH(l, r, b, t, n, f);

    // Transform NDC space [-1,+1]^2 to texture space [0,1]^2
    XMMATRIX T(
        0.5f, 0.0f, 0.0f, 0.0f,
        0.0f, -0.5f, 0.0f, 0.0f,
        0.0f, 0.0f, 1.0f, 0.0f,
        0.5f, 0.5f, 0.0f, 1.0f);

    XMMATRIX S = lightView * lightProj;

    XMStoreFloat4x4(&m_xmf4x4LightViewProj[nShadowIndex], XMMatrixTranspose(S));

    S = S * T;

    XMStoreFloat4x4(&m_xmf4x4ShadowTransform[nShadowIndex], XMMatrixTranspose(S));

    CB_SHADOW cbShadow{ m_xmf4x4ShadowTransform, m_xmf4x4LightViewProj, m_pLight->GetPosition(), m_xmf4x4CascadedViewProj};

    m_ubShadowCB->CopyData(0, cbShadow);
    pd3dCommandList->SetGraphicsRootConstantBufferView(3, m_ubShadowCB->Resource()->GetGPUVirtualAddress());
    pd3dCommandList->SetGraphicsRoot32BitConstants(2, 1, &nShadowIndex, 1);
}

here's graphics root signature. there's few korean comment. but not important

ID3D12RootSignature* CScene::CreateGraphicsRootSignature(ID3D12Device* pd3dDevice)
{
    ID3D12RootSignature* pd3dGraphicsRootSignature = NULL;
    CD3DX12_ROOT_PARAMETER pd3dRootParameters[8];

    //32비트 루트 상수
    pd3dRootParameters[0].InitAsConstants(28, 0, 0, D3D12_SHADER_VISIBILITY_ALL);
    pd3dRootParameters[1].InitAsConstants(19, 1, 0, D3D12_SHADER_VISIBILITY_ALL);
    pd3dRootParameters[2].InitAsConstants(2, 2, 0, D3D12_SHADER_VISIBILITY_ALL);

    //UploadBuffer 클래스를 이용하여 업로드
    pd3dRootParameters[3].InitAsConstantBufferView(3);

    //구조화 된 버퍼, stdafx.h의 CreateBufferResource 함수 이용해 업로드
    pd3dRootParameters[4].InitAsShaderResourceView(0, 1);
    pd3dRootParameters[5].InitAsShaderResourceView(1, 1);

    CD3DX12_DESCRIPTOR_RANGE shadowMapRange(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 3, 0, 0, D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND); // 3개, 0 ~ 2
    CD3DX12_DESCRIPTOR_RANGE texRange(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 6, 3, 0, D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND); // 6개, 3 ~ 8

    //디스크립터 테이블 이용하여 업로드
    pd3dRootParameters[6].InitAsDescriptorTable(1, &shadowMapRange); //쉐도우 맵 - 6, 7, 8
    pd3dRootParameters[7].InitAsDescriptorTable(1, &texRange); //텍스쳐 배열 - 9, 10, 11, 12, 13, 14

    auto staticSamplers = GetStaticSamplers();

    CD3DX12_ROOT_SIGNATURE_DESC d3dRootSignatureDesc(_countof(pd3dRootParameters), pd3dRootParameters, (UINT)staticSamplers.size(), staticSamplers.data(), D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT);

    ID3DBlob* pd3dSignatureBlob = NULL;
    ID3DBlob* pd3dErrorBlob = NULL;
    auto tmp = ::D3D12SerializeRootSignature(&d3dRootSignatureDesc, D3D_ROOT_SIGNATURE_VERSION_1, &pd3dSignatureBlob, &pd3dErrorBlob);

    if (pd3dErrorBlob != NULL)
    {
        auto tmp = (char*)pd3dErrorBlob->GetBufferPointer();
        std::string p = tmp;
        p.c_str();
    }

    pd3dDevice->CreateRootSignature(0, pd3dSignatureBlob->GetBufferPointer(), pd3dSignatureBlob->GetBufferSize(), __uuidof(ID3D12RootSignature), (void**)&pd3dGraphicsRootSignature);

    if (pd3dSignatureBlob)
        pd3dSignatureBlob->Release();

    if (pd3dErrorBlob)
        pd3dErrorBlob->Release();

    return(pd3dGraphicsRootSignature);
}

Solution

  • Instead of:

    cbuffer cbLightInfo : register(b2)
    {
    int nLights : packoffset(c0);
    int nShadowIndex : packoffset(c4); // - this is the constant
    }
    

    try making it:

    int nLights : packoffset(c0.x);
    int nShadowIndex : packoffset(c0.y);