HLSL mul()变量澄清

时间:2013-05-16 03:57:20

标签: c++ directx hlsl

HLSL的mul(x,y)参数表示here:说明

  • 如果x是向量,则将其视为行向量。
  • 如果y是向量,则将其视为列向量。

这是否遵循以下含义:

一个。

  • 如果x是向量,则y被视为row-major matrix
  • 如果y是向量,则x被视为column-major matrix

因为ID3DXBaseEffect :: SetMatrix()传入row-major matrix,因此我按照以下顺序使用传递到着色器的矩阵:

离。 Output.mPosition = mul( Input.mPosition, SetMatrix()value );

我刚开始使用着色器和当前重新学习我的矩阵数学。如果有人能澄清这一点会很好。

2 个答案:

答案 0 :(得分:15)

没有。术语“行主要”和“列主要”纯粹指的是存储器中矩阵组件的存储的顺序。它们与矩阵和向量的乘法顺序无关。实际上,D3D9 HLSL mul调用在所有情况下都将矩阵参数解释为列主要。 ID3DXBaseEffect::SetMatrix()调用将其矩阵参数解释为row-major,并在后台转换为mul预期的列主要顺序。

如果你有一个抽象的矩阵:

[ a b c d ]
[ e f g h ]
[ i j k l ]
[ m n o p ]

然后以行主要顺序存储时,其内存如下所示:

a b c d e f g h i j k l m n o p

即。行的元素在内存中都是连续的。如果按列主要顺序存储,其内存将如下所示:

a e i m b f j n c g k o d h l p

列的元素都是连续的。但是,这对哪个元素的影响正好为零。无论哪种方式,元素b仍然在第一行和第二列。元素的标记没有改变,只是它们被映射到内存的方式。

如果在C中声明类似float matrix[rows][cols]的数组,那么您正在使用行主存储。但是,其他一些语言(如FORTRAN)默认使用列主存储作为其多维数组; OpenGL也使用列主存储。

现在,完全单独地,有另一个约定选择,即是使用行向量还是列向量数学。这与矩阵的内存布局没有任何关系,但它会影响你构建矩阵的方式以及乘法的顺序。如果你使用行向量,你将进行向量矩阵乘法:

            [ a b c d ]
[x y z w] * [ e f g h ] = [x*a + y*e + z*i + w*m, ... ]
            [ i j k l ]
            [ m n o p ]

如果你使用列向量,那么你将进行矩阵向量乘法:

[ a b c d ]   [ x ]
[ e f g h ] * [ y ] = [x*a + y*b + z*c + w*d, ... ]
[ i j k l ]   [ z ]
[ m n o p ]   [ w ]

这是因为在行向量数学中,向量实际上是1×n矩阵(单行),而在列向量数学中它是n×1矩阵(单列),以及关于什么的规则允许矩阵的大小相乘以确定顺序。 (你不能将4×4矩阵乘以1×4矩阵,但你可以将4×4矩阵乘以4×1矩阵。)

注意,矩阵在上述两个方程之间没有变化;只有对矢量的解释发生了变化。

所以,回到原来的问题:

当你将一个向量传递给HLSL的mul时,它会根据它的参数自动“正确地”解释它。如果向量在右边,它是一个行向量,如果它在左边,它就是一个列向量。

然而,矩阵总是以相同的方式解释。矩阵是一个矩阵,无论它是左侧的行向量还是右侧的列向量。您可以自由决定是否在代码中使用行向量或列向量数学,只要您对它保持一致即可。虽然D3DX数学库使用行向量,但HLSL在这一点上是不可知的。

事实证明,由于某些原因,在D3D9 HLSL中,mul总是希望矩阵以列主顺序存储。但是,D3DX数学库以行主顺序存储矩阵,正如文档所述,ID3DXBaseEffect::SetMatrix()期望其输入按主行顺序排列。它在幕后进行转置,以准备与mul一起使用的矩阵。

BTW,D3D11 HLSL默认为列主要顺序,但允许您使用编译器指令来告诉它使用行主顺序。对于行向量与列向量数学,它仍然是不可知的。 OpenGL GLSL也使用列主要顺序,但是(据我所知)没有提供改变它的方法。

进一步阅读这些问题:

答案 1 :(得分:8)

是的,如果x是向量,则x被视为行主向量,y被视为行主矩阵;对于行主要矩阵系统,反之亦然:

float4 transformed = mul(position, world);

和专栏:

float4 transformed = mul(world, position);

由于矩阵乘法的工作方式,如果矩阵是列主要的,那么您必须乘以列向量以获得正确的结果。如果矩阵是行主要的,则必须预先乘以行向量。

实际上,hlsl并不关心你的矩阵是行还是列主要,你可以按正确的顺序应用向量乘法来得到正确的结果。