关于HLSL中的矩阵传参

 

一个非常简单的问题,但是网上的资料群魔乱舞,这里备忘一下。

首先定义好数学意义上的两种写法,和存储方式无关:

\[T_L = \left[ \begin{matrix} 1 & 0 & 0 & x \\ 0 & 1 & 0 & y \\ 0 & 0 & 1 & z \\ 0 & 0 & 0 & 1 \end{matrix} \right] ~~~~~~ T_R = \left[ \begin{matrix} 1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & 1 & 0 \\ x & y & z & 1 \end{matrix} \right]\]

利用它们对点进行变换的方式分别是$u’ = T_Lu$和$v’ = vT_R$,其中$u$是列向量,$v$是行向量。

然后我们定义两种存储方式:行主序(row-major)和列主序(col-major)。对某个矩阵:

\[M = \left[ \begin{matrix} m_{11} & m_{12} & m_{13} & m_{14} \\ m_{21} & m_{22} & m_{23} & m_{24} \\ m_{31} & m_{32} & m_{33} & m_{34} \\ m_{41} & m_{42} & m_{43} & m_{44} \end{matrix} \right]\]

行主序在内存中把它排成这样:

\[\begin{matrix} m_{11} & m_{12} & m_{13} & m_{14} & m_{21} & \cdots & m_{44} \end{matrix}\]

而列主序则是这样:

\[\begin{matrix} m_{11} & m_{21} & m_{31} & m_{41} & m_{12} & \cdots m_{44} \end{matrix}\]

现在假如我们使用DirectXMath作为host端的数学库,它是行主序存储的,构造变换矩阵的方式是上面的$T_R$那种。如果我们把要把它的矩阵传进shader用,那么就需要做一个行-列存储方式的转换。这可以通过一个转置操作来完成。转置是个纯数学操作,但是反映到内存排布上,就恰好等价于“数学上没做操作,存储上换了种方式”。

Done.