D3D11 HLSL编译器是否会预先计算矩阵?

时间:2019-02-24 07:34:31

标签: matrix-multiplication directx-11 hlsl

假设我们在HLSL中有一个几何着色器(模型5.0),其中包含用于缩放的矩阵和用于转换的矩阵:

float4x4 scale;
scale[0] = float4( s,   0.0f, 0.0f, 0.0f);
scale[1] = float4(0.0f,  s,   0.0f, 0.0f);
scale[2] = float4(0.0f, 0.0f,  s,   0.0f);
scale[3] = float4(0.0f, 0.0f, 0.0f, 1.0f);

float4x4 translation;
translation[0] = float4(1.0f, 0.0f, 0.0f, 0.0f);
translation[1] = float4(0.0f, 1.0f, 0.0f, 0.0f);
translation[2] = float4(0.0f, 0.0f, 1.0f, 0.0f);
translation[3] = float4( x,    y,    z,   1.0f);

这里s是缩放系数,xyz是每个轴上的平移量。通过将它们相乘,可以将这些矩阵组合成一个矩阵:

float4x4 combined;
combined = mul(scale, translation);

但是,也可以在纸上进行乘法,然后直接初始化组合矩阵。这样做将产生以下结果:

float4x4 combined;
combined[0] = float4( s,   0.0f, 0.0f, 0.0f);
combined[1] = float4(0.0f,  s,   0.0f, 0.0f);
combined[2] = float4(0.0f, 0.0f,  s,   0.0f);
combined[3] = float4( x,    y,    z,   1.0f);

上面的示例非常简单,但是我总共有4个矩阵,分别具有缩放,旋转和平移,因此如您所知,直接初始化该组合矩阵非常麻烦。

因此,如果编译器在编译时执行此操作,则出于可读性原因,最好单独初始化矩阵,但如果它不在编译时进行合并,而是在运行时进行合并,则最好初始化出于性能原因合并矩阵。

因此,我的问题是:

编译器会在编译过程中自动合并这些矩阵吗?

我当前正在使用D3DCompileFromFile函数来编译着色器。我不知道该函数是否使用与Visual Studio中的编译器相同的编译器,但是如果不使用,而Visual Studio中的编译器更好,我可以在构建过程中编译着色器,然后只读取{ {1}}文件。

此外,此几何体着色器正在生成广告牌,因此我无法在CPU上计算这些矩阵,因为每个广告牌都有不同的矩阵。

1 个答案:

答案 0 :(得分:0)

虽然HLSL编译器将执行一些优化,并且在将编译器着色器字节码转换为特定于硬件的微代码时,驱动程序将执行其他优化,但是与传统C / C ++编译器相比,HLSL编译器的攻击性有一定的限制。

由于每个场景多次执行同一个着色器,因此通常在着色器常量中提供预先组合的矩阵。例如:

cbuffer Parameters : register(b0)
{
    float4x4 World
    float3x3 WorldInverseTranspose
    float4x4 WorldViewProj
};

这里提供世界矩阵,世界矩阵的逆转置和预先组合的世界视图投影矩阵。