您的位置:首页 > 其它

为什么DirectX 11 在把矩阵(例如View矩阵)传给shader之前要进行转置

2015-11-16 16:47 786 查看
一,

在DirectX11里, 能看到这样的代码

D3DXMatrixTranspose(&worldMatrix, &worldMatrix);

D3DXMatrixTranspose(&viewMatrix, &viewMatrix);

D3DXMatrixTranspose(&projectionMatrix, &projectionMatrix);

目的是把矩阵转置, 之后再传给shader

二,

根据3D数学的相关知识, 把一个矩阵代表的变换作用于一个Vector(或Point), 需要矩阵和Vector相乘

如果矩阵是row-major, 则矩阵在右, Vector在左

如果矩阵是column-major, 则矩阵在左, Vector在右 (例如UNITY)

注意这里的左乘/右乘和内存中的数据存放方式没有关系, 它只是纯粹的数学

三,

下面来看在DirectX11里的shader代码

output.position = mul(input.position, worldMatrix);

output.position = mul(output.position, viewMatrix);

output.position = mul(output.position, projectionMatrix);

这里的矩阵都已经是转置过的矩阵, 即column-major, 但是为什么它们都是在乘法的右侧呢

根据前面所说的, column-major矩阵应该是在乘法左边才对

四, 详细解释

矩阵位置索引

[ 1   2     3    4 ]

[ 5   6     7    8 ]

[ 9   10
11   12 ]

[ 13 14  
15   16 ]

如果有一个矩阵形如

[ a  b  c d]

[ e  f   g h]

[ i   j   k  l ]

[m n  o p]

那么

行主, 内存位置索引为

a b c d e f 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

行主乘法如下

V * M = 数字为内存位置索引[V * M[1,5,9,13], ...] = 数字为矩阵位置索引[V * M[1,5,9,13], ...] = [V * M[a,e,i,m], ...]

列主乘法如下

M * V = 数字为内存位置索引[M[1,5,9,13] * V, ...] = 数字为矩阵位置索引[M[1,2,3,4] * V, ...] = [V * M[a,e,i,m], ...]

在HLSL中比较特殊, 按理说矩阵在右侧应该是行主乘法, 但是HLSL又默认期望所有矩阵都是列主

所以HLSL中的矩阵乘法和前面有所不同, 如下

V * M = 数字为内存位置索引[V * M[1,2,3,4], ...] = 数字为矩阵位置索引[V * M[1,2,3,4], ...] = [V * M[a,e,i,m], ...]

五, 为什么要这样? 因为速度

根据
http://www.gamedev.net/topic/662986-hlsl-mul-and-rowcolumn-major-matricies-in-directx

里的回复

HLSL生成的shader代码型如

dp4 oPos.x,  v0, c0

dp4 oPos.y,  v0, c1 

dp4 oPos.z,  v0, c2

dp4 oPos.w, v0, c3

正如[四,]里写出的HLSL乘法公式, 注意是数字为内存索引位置的那个

而使用普通的列主乘法, shader代码会变成

mul r0, v0.y, c1

mad r0, c0, v0.x, r0

mad r0, c2, v0.z, r0

mad oPos, c3, v0.w, r0

回复者的原话是

"Having single column in one constant register allows to quickly calc resulting vector component
with one dot instruction."

参考资料:
http://www.gamedev.net/topic/662986-hlsl-mul-and-rowcolumn-major-matricies-in-directx/ http://xboxforums.create.msdn.com/forums/t/112276.aspx http://stackoverflow.com/questions/16578765/hlsl-mul-variables-clarification http://www.rastertek.com/dx11tut04.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息