You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

D3D11着色器仅能读取顶点位置/纹理/法线,无法读取骨骼权重与索引求助

故障核心原因
  • 第一是HLSL顶点输入语义与C++输入布局不匹配:你在C++的输入布局中为骨骼权重指定的语义名是BLENDWEIGHT,但HLSL的SkinnedInput结构里权重字段用的是WEIGHT语义,两者名称完全不一致,D3D11无法将顶点缓冲区的权重数据映射到着色器输入变量,导致读到的是未初始化的无效值。
  • 第二是存在潜在的C结构体内存对齐问题:你没有显式指定C顶点结构体的对齐规则,不同编译器/编译选项可能会在结构体成员之间插入填充字节,导致D3D11_APPEND_ALIGNED_ELEMENT计算的偏移量和实际结构体成员偏移不匹配,最终数据读取错位。
  • 可选排查项:顶点缓冲区绑定的步长(stride)设置错误,如果调用IASetVertexBuffers时传入的步长不等于sizeof(SkinnedMesh),也会导致顶点数据读取错位,蒙皮相关字段无法拿到正确值。
修复步骤
  1. 修正HLSL的权重语义,将SkinnedInput里的权重字段语义改为和输入布局一致的BLENDWEIGHT:
struct SkinnedInput
{
    float3 Position : POSITION;   
    float2 Tex : TEXCOORD;          
    float3 Normal : NORMAL;
    float4 Weights : BLENDWEIGHT; // 此处将WEIGHT修改为BLENDWEIGHT
    uint4 BoneIndices : BLENDINDICES;  
};
  1. 显式指定C++顶点结构体的对齐,避免编译器插入填充字节,修改后的顶点结构体定义如下:
#pragma pack(push, 16) // 按16字节对齐,匹配HLSL默认结构体对齐规则
struct SkinnedMesh
{
    XMFLOAT3 Position;
    XMFLOAT2 Texture;
    XMFLOAT3 Normal;
    XMFLOAT4 Weight;
    XMUINT4 BoneIndices;
};
#pragma pack(pop)
  1. 检查IASetVertexBuffers调用,确保传入的顶点步长正确:
UINT stride = sizeof(SkinnedMesh);
UINT offset = 0;
_pd3dDeviceContext->IASetVertexBuffers(0, 1, &pVertexBuffer, &stride, &offset);
  1. 可选优化:确保骨骼权重的4个分量和为1,避免蒙皮计算出现异常拉伸。

内容的提问来源于stack exchange,提问作者문형준

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 01:15:03