我正在使用dx12和hlsl,这个特定的根常数似乎不改变或不用于索引。
这是HLSL代码
#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);
当我像这样使用nshadowwindex
#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;
}
这个着色器总是返回相同的结果,因为nshadowwindex总是固定为0。
,这就是我设置变量的方式。(还有许多其他变量,但对这个不那么重要)如你所见,我要做的是级联阴影贴图。
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);
}
这里是图形根签名。几乎没有韩国人对此发表评论。但不重要
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);
}
而不是:
cbuffer cbLightInfo : register(b2)
{
int nLights : packoffset(c0);
int nShadowIndex : packoffset(c4); // - this is the constant
}
尝试:
int nLights : packoffset(c0.x);
int nShadowIndex : packoffset(c0.y);