一、mul函数
mul函数的作用是完成向量与矩阵的乘法运算,有如下两种形式
1、mul(v, M):行向量v乘以矩阵M
2、mul(M, v):矩阵乘以列向量v
默认情况下,矩阵是按列选取(column-major matrix picking),也就是每个寄存器存储矩阵的一列,M=(c0, c1, c2, c3);如果是按行选取(row-major matrix picking),那么每个寄存器存储的是矩阵的一行.
下面说明在默认按列选取情况下,mul的两种实现方式
1、mul(v, M)
dp4 o0.x, v0, c0
dp4 o0.y, v0, c1
dp4 o0.z, v0, c2
dp4 o0.w, v0, c3
dp4的作用是完成4维向量的点积,结果存储在o0中
2、mul(M, v)
mul r0, c1, v0.y
mad r0, c0, v0.x, r0
mad r0, c2, v0.z, r0
mad o0, c3, v0.w, r0
实现原理:o0 = c0*x + c1*y + c2*z + c3*w
其中mad完成是mul add两个操作,即mad d, a, b, c <<==>> d = a * b + c
对于在hlsl中,如果对顶点进行变换,选取用那个形式进行计算取决于矩阵的存储形式以拾取方式,具体情况如下:
1、如果用Effect::SetMatrix进行矩阵的设置,那么就用mul(v, M),因为在SetMatrix时,会进行矩阵的转置操作。或者用mul(v, transpos(M))
2、如果不用Effect::SetMatrix进行矩阵的设置,比如Ogre,那么传入shader中的矩阵就是按行存储的,故采用mul(M, v)
下面截图分别是矩阵在GPU的存储形式和CPU端的存储形式
GPU 端
CPU端
可见在没有通过Effect::SetMatrix设置时,存储表现形式是一样的。最后一列表示的是平移变换
二、矩阵构造
在HLSL中矩阵的构造如下:
float4x4 mt = float4x4(v0, v1, v2, v3);
= {v00 , v01 , v02, v03 ,
v10 , v11 , v12 , v13 ,
v20 , v21 , v22 , v13 ,
v30 , v31 , v32 , v33}
即按行序构造。
mt[0]获取的是第0行元素的值v0