matrix-multiplication - D3D11 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
是一个比例系数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 编译器将执行一些优化,并且驱动程序将在将编译器着色器字节码转换为特定于硬件的微码时执行额外的优化,但是与传统 C/C++ 编译器相比,HLSL 编译器的激进程度是有限的。
因为同一个着色器在每个场景中执行多次,所以通常在着色器常量中提供预先组合的矩阵。例如:
cbuffer Parameters : register(b0)
{
float4x4 World
float3x3 WorldInverseTranspose
float4x4 WorldViewProj
};
在这里,我们提供了世界矩阵、世界矩阵的逆转置和预组合的世界观投影矩阵。
推荐阅读
- java - 如何创建一个接受数组参数并初始化底层数组中的值的构造函数?
- authentication - 如何为无限数量的客户端保护非交互式身份验证系统?
- algorithm - 在给定条件下可以形成的最大测验数
- django - 错误:django.core.exceptions.ImproperlyConfigured:SECRET_KEY 设置不能为空。在将应用程序部署到heroku时
- context-free-grammar - 是否存在上下文无关文法,其中所有符号都无用?
- here-api - Android Here-lite SDK 中的 getScaleFromZoomLevel 等效项
- java - Java:使用代码从文件夹中添加外部库
- android - 如何在水平进度条android中设置进度
- python - 从主 SQL 表中的列创建新表
- python - 如何从 2 个不同的数据集中并排显示 seaborn 图?