Shader除了position,texcoord,normal之外不获取Vertex数据

Shader does not get Vertex data except position, texcoord, normal

我想读取骨骼的重量,但着色器无法读取数据

这是我的顶点类型

struct SkinnedMesh
{

XMFLOAT3 Position;
XMFLOAT2 Texture;
XMFLOAT3 Normal;
XMFLOAT3 Weight;
UINT BoneIndices[4];
};

这是初始化着色器描述

// Create the vertex input layout description.
polygonLayout[0].SemanticName = "POSITION";
polygonLayout[0].SemanticIndex = 0;
polygonLayout[0].Format = DXGI_FORMAT_R32G32B32_FLOAT;
polygonLayout[0].InputSlot = 0;
polygonLayout[0].AlignedByteOffset = 0;
polygonLayout[0].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
polygonLayout[0].InstanceDataStepRate = 0;

polygonLayout[1].SemanticName = "TEXCOORD";
polygonLayout[1].SemanticIndex = 0;
polygonLayout[1].Format = DXGI_FORMAT_R32G32_FLOAT;
polygonLayout[1].InputSlot = 0;
polygonLayout[1].AlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT;
polygonLayout[1].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
polygonLayout[1].InstanceDataStepRate = 0;

polygonLayout[2].SemanticName = "NORMAL";
polygonLayout[2].SemanticIndex = 0;
polygonLayout[2].Format = DXGI_FORMAT_R32G32B32_FLOAT;
polygonLayout[2].InputSlot = 0;
polygonLayout[2].AlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT;
polygonLayout[2].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
polygonLayout[2].InstanceDataStepRate = 0;

polygonLayout[3].SemanticName = "BLENDWEIGHT";
polygonLayout[3].SemanticIndex = 0;
polygonLayout[3].Format = DXGI_FORMAT_R32G32B32_FLOAT;
polygonLayout[3].InputSlot = 0;
polygonLayout[3].AlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT;
polygonLayout[3].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
polygonLayout[3].InstanceDataStepRate = 0;

polygonLayout[4].SemanticName = "BLENDINDICES";
polygonLayout[4].SemanticIndex = 0;
polygonLayout[4].Format = DXGI_FORMAT_R32G32B32A32_UINT;
polygonLayout[4].InputSlot = 0;
polygonLayout[4].AlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT;
polygonLayout[4].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
polygonLayout[4].InstanceDataStepRate = 0;

numElements = sizeof(polygonLayout) / sizeof(polygonLayout[0]);

// Create the vertex input layout.8
if (FAILED(_Device->CreateInputLayout(polygonLayout, numElements, vertexShaderBuffer->GetBufferPointer(), vertexShaderBuffer->GetBufferSize(), &Layout)))
{
    MSG_BOX("Failed to create vertex input layout.");
    return E_FAIL;
}
return S_OK;

这是hlsl代码

struct SkinnedInput
{
    float3 Position : POSITION;   
    float2 Tex : TEXCOORD;          
    float3 Normal : NORMAL;
    float4 Weights : WEIGHT;
    uint4 BoneIndices : BLENDINDICES;  
};

struct SkinnedOutput
{
    float4 Position : SV_POSITION;
    float2 Tex : TEXCOORD;
    float3 Normal : NORMAL;
};

SkinnedOutput main(SkinnedInput _Input)
{
    SkinnedOutput Out = (SkinnedOutput) 0;

    float weight[4];
    //weight[0] = _Input.Weights.x;
    //weight[1] = _Input.Weights.y;
    //weight[2] = _Input.Weights.z;
    //weight[3] = _Input.Weights.w;

    Out.Position = mul(float4(_Input.Position, 1.f), WorldMatrix);
    Out.Position = mul(Out.Position, ViewMatrix);
    Out.Position = mul(Out.Position, ProjectionMatrix);

    Out.Tex = _Input.Tex;

    Out.Normal = normalize(mul(float4(_Input.Normal, 0.f), WorldMatrix));

    
    return Out;

}

当我调试hlsl 时,weights 和boneindices 中没有数据。 我读过weights和boneindicies以外的int值,但是看不懂

即使我改变数据顺序读取它,也只读取position、texcoord和normal

有人知道吗?

我更改了结构和布局 decs

struct SkinnedMesh
{
    XMFLOAT3 Position;
    XMFLOAT2 Texture;
    XMFLOAT3 Normal;
    XMFLOAT4 Weight;
    XMUINT4 BoneIndices;
};

D3D11_INPUT_ELEMENT_DESC polygonLayout[] =
{
    { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
    { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 },
    { "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 },
    { "BLENDWEIGHT", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 },
    { "BLENDINDICES", 0, DXGI_FORMAT_R32G32B32A32_UINT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 } };

但结果是一样的..

这是compiler/runtime优化的案例。

由于您在着色器中根本不使用混合权重,因此最终不会获取数据。

要正确测试它,您可以制作类似的东西:

struct SkinnedOutput
{
    float4 Position : SV_POSITION;
    float2 Tex : TEXCOORD;
    float3 Normal : NORMAL;
    float4 Weights : WEIGHT;
};

并确保分配它:

 Out.Weights = _Input.Weights;

检查着色器反汇编时可见,您的输入声明是:

// Input signature:
//
// Name                 Index   Mask Register SysValue  Format   Used
// -------------------- ----- ------ -------- -------- ------- ------
// POSITION                 0   xyz         0     NONE   float   xyz 
// TEXCOORD                 0   xy          1     NONE   float   xy  
// NORMAL                   0   xyz         2     NONE   float   xyz 
// WEIGHT                   0   xyzw        3     NONE   float       
// BLENDINDICES             0   xyzw        4     NONE    uint  

注意used标志是空的,所以当你检查变量声明时:

vs_5_0
dcl_globalFlags refactoringAllowed
dcl_constantbuffer CB0[12], immediateIndexed
dcl_input v0.xyz
dcl_input v1.xy
dcl_input v2.xyz
dcl_output_siv o0.xyzw, position
dcl_output o1.xy
dcl_output o2.xyz
dcl_temps 2

可以看到shader只声明了v0(position),v1(uv),v2(texcoords),没有用到的根本没有声明。

请注意,编译器非常积极地删除未使用的代码,因此即使您取消注释:

float weight[4];
weight[0] = _Input.Weights.x;
weight[1] = _Input.Weights.y;
weight[2] = _Input.Weights.z;
weight[3] = _Input.Weights.w;

但权重不会写入输出,它也会被删除。