变换序列:投影纹理(HLSL)

6
当我阅读nvidia上的关于投影纹理(9.3.2)的文章this article on Projective Texturing (9.3.2)时,我看到了这张图片:


(来源:nvidia.com)

我对转换的顺序感到困惑。这是因为我学习矩阵乘法是从左到右阅读,并且我认为变换的顺序应该按照以下顺序进行:


(来源:nvidia.com)

现在我的问题如下:

矩阵乘法不满足交换律,那么我应该按什么顺序进行乘法运算?

如果确实是与正常对象的变换序列相同的顺序,为什么要这样书写?

所谓的相同顺序指的是类似于这个 hlsl 代码:

float4 worldPosition        = mul(input.Position, World);
float4 viewPosition         = mul(worldPosition, View);
output.Position             = mul(viewPosition, Projection);

最后(这是可选的,但对于其他想知道相同内容的人可能会有用),您将如何编写HLSL代码以执行此投影纹理乘法,或者如果通过XNA传递完整矩阵,则将如何进行转换。

1个回答

4

您的变换可以用符号表示为

y = T P V W x

其中:

x = (x0, y0, z0, w0)T:对象坐标(列向量4x1)
y = (s, t, r, q)T:窗口空间坐标(列向量4x1)
W:世界建模矩阵(4x4)
V:视图建模矩阵(4x4)
P:投影矩阵(4x4)
T:视口变换矩阵(4x4)

计算方法如下:

y = T (P (V (W x)))

即从右到左。HLSL 代码应该是:

float4 worldPosition  = mul(World, input.Position);     // W x
float4 viewPosition   = mul(View, worldPosition);       // V (W x)
float4 projPosition   = mul(Projection, viewPosition);  // P (V (W x))
float4 vportPosition  = mul(Viewport, projPosition);    // T (P (V (W x)))

谢谢你的回答。我想这就是投影纹理的转换,就像文章中的图像一样。我还有两个问题:
  • y = T (P (V (W x))) 是否等同于 (x W) V) P) T = y?
- Alexander van der Zalm
设 y = T P V W,x = T (P (V (W x)))。将 x 的转置表示为 xt(列向量 4x1 变成行向量 1x4,4x4 矩阵在对角线处反射)。则 yt = (TPVWx)t = xt Wt Vt Pt Tt = (((xt Wt) Vt) Pt) Tt。 - Jiri Kriz
我评论的另一部分是:(由于意外无法编辑我的帖子)我感到困惑的原因是因为文章提到:oPosition = Mul(modelViewProj, position);而在HLSL代码中之前则是相反的。
  • 如果不是这样,为什么要这样写,几何上是否意味着与(x W)V)P)T = y 不同的东西?还是说这是某种数学约定,有时从右到左书写/阅读?HLSL编译器是否知道这两种符号表示法之间的区别?
- Alexander van der Zalm
当你解释矩阵变换的4x1和1x4(转置)版本之间的区别时,我有了灵光一现的时刻。所以为了完全清楚:如果要使转置版的一系列矩阵乘法与非转置版的矩阵乘法相同,必须按相反的顺序编写它们吗?谢谢! - Alexander van der Zalm
我的最后一个问题是,当它是float4时,hlsl编译器如何知道你是指x = 4x1还是1x4? - Alexander van der Zalm
(a) 操作 y = TPVWxyt = xt Wt Vt Pt Tt 是等价的。我更喜欢使用数学中通常的 y = TPVWx。 (b) HLSL编译器可以推断正确的操作,因为在任何 mul(A,B) 中,矩阵 AB 的内部维度必须相等。参见例如 link - Jiri Kriz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接