Matrix 如何在DirectX中将float3x3传递给HLSL着色器?

Matrix 如何在DirectX中将float3x3传递给HLSL着色器?,matrix,directx,hlsl,Matrix,Directx,Hlsl,我在DirectX中将3x3矩阵通过常量缓冲区传递到着色器时遇到问题。这是我定义常量缓冲区的方式: 在.cpp中: struct PostProcessConvolutionCB { float screenWidth; float screenHeight; float sum; XMFLOAT3X3 kernel; }; 在.hlsl中: struct PostProcessConvolutionCB { float screenWidth;

我在DirectX中将3x3矩阵通过常量缓冲区传递到着色器时遇到问题。这是我定义常量缓冲区的方式:

在.cpp中:

struct PostProcessConvolutionCB {
    float screenWidth;
    float screenHeight;
    float sum;
    XMFLOAT3X3 kernel;
};
在.hlsl中:

struct PostProcessConvolutionCB {
    float screenWidth;
    float screenHeight;
    float sum;
    float3x3 kernel;
};
ConstantBuffer<PostProcessConvolutionCB> cb : register(b0);

struct PixelShaderInput {
    float4 Position : SV_Position;
};

float4 main(PixelShaderInput IN) : SV_Target {
    return float4(cb.kernel[1][1], 0.f, 0.f, 1.f);
}
似乎每行都与4个浮点数对齐。将矩阵更改为4x4会有所帮助,但我想一定有办法使用float3x3类型


如何正确处理这个问题?

你要解决的问题是HLSL的打包规则不同于C++。见:

HLSL打包规则类似于使用Visual Studio执行
#pragma pack 4
,它将数据打包为4字节边界。此外,HLSL对数据进行打包,使其不会跨越16字节的边界

还要记住,默认情况下,HLSL使用“列主”矩阵,而DirectXMath使用“行主”。这就是为什么您会看到许多示例将矩阵从
XMFLOAT?X?
转换为HLSL常量缓冲区结构。看

通常,您最好的选择是对HLSL矩阵使用
XMFLOAT4X4
。节省少量恒定缓冲区内存的一个选项是在HLSL中使用(对于蒙皮非常有用,尤其是在有许多不包含投影变换的骨骼的情况下):

struct SkinnedEffectConstants
{
…
    XMVECTOR bones[MaxBones][3];
};

在C++中使用:

for (size_t i = 0; i < count; i++)
{
    XMMATRIX boneMatrix = XMMatrixTranspose(XMLoadFloat4x3(…));

    boneConstant[i][0] = boneMatrix.r[0];
    boneConstant[i][1] = boneMatrix.r[1];
    boneConstant[i][2] = boneMatrix.r[2];
}
(大小i=0;i { XMMATRIX-boneMatrix=XMMATRIX-transpose(XMLoadFloat4x3(…); boneConstant[i][0]=boneMatrix.r[0]; boneConstant[i][1]=boneMatrix.r[1]; boneConstant[i][2]=boneMatrix.r[2]; }
是的,这很有道理。我采用了float4x3方法,而且效果很好。非常感谢。
for (size_t i = 0; i < count; i++)
{
    XMMATRIX boneMatrix = XMMatrixTranspose(XMLoadFloat4x3(…));

    boneConstant[i][0] = boneMatrix.r[0];
    boneConstant[i][1] = boneMatrix.r[1];
    boneConstant[i][2] = boneMatrix.r[2];
}