假设我们在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
是一个缩放系数,x
,y
,z
是每个轴的平移量。我们可以通过乘以它们将这些矩阵组合成一个矩阵:
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中的编译器更好,我可以在构建期间编译着色器,然后只读取.cso
文件。
此外,这个几何着色器正在生成广告牌,因此我无法在CPU上计算这些矩阵,因为每个广告牌都有不同的矩阵。
虽然HLSL编译器将执行一些优化,并且驱动程序将在将编译器着色器字节代码转换为特定于硬件的微代码时执行其他优化,但HLSL编译器与传统C / C ++编译器相比具有多大程度的限制。
因为每个场景执行相同的着色器多次,所以在着色器常量中提供预合成矩阵是很常见的。例如:
cbuffer Parameters : register(b0)
{
float4x4 World
float3x3 WorldInverseTranspose
float4x4 WorldViewProj
};
在这里,我们提供世界矩阵,世界矩阵的逆转置,以及预组合的世界 - 视图 - 投影矩阵。