注册 登录
开源计算机图形学社区(Open Source Computer Graphics Community) |OpenGPU Forum (2007-2013)| OpenGPU Project 返回首页

zgrapher的个人空间 http://www.opengpu.org/?38964 [收藏] [复制] [分享] [RSS]

日志

关于directx 矩阵行主序和列主序的总结

热度 1已有 1738 次阅读2015-9-16 16:09 | directx

有些同学可能遇到过这样的问题,用dx的shader做渲染,本应是这样的渲染结果:
但渲染出来时是这样的:
问题的原因很可能出再矩阵的主序设置上。先说问题的解决方案,拿Dx9来举例。
方案一:编译shader时,传递D3DXSHADER_PACKMATRIX_ROWMAJOR标志。
方案二:给shader传递矩阵之前,对矩阵坐下转置。
方案三:在shader开头加上"#pragma pack_matrix( row_major )“。
方案四:在shader uniform声明前加上row_maor ,比如“row_maor float4x4 g_mWorldViewProjection;”。
方案五:mul指令中将矩阵放在前面,比如:"mul(g_mWorldViewProjection, vPos);"。

接下来讲问题的原理。
dx使用行矩阵,矩阵在内存中是按行主序存储的。
m11, m12, m13, m14
m21, m22, m23, m24
m31, m32, m33, m34
m41, m42, m43, m44
这样一个矩阵,在内存中是这样:m11, m12, m13, m14, m21, m22, m23, m24 ... m41, m42, m43, m44。
数据从内存传输至shader uniform寄存器时,是从前到后依次存储的。比如矩阵存储在c0、c1、c2、c3四个寄存器中,结果是这样:
c0: m11, m12, m13, m14
c1: m21, m22, m23, m24
c2: m31, m32, m33, m34
c3: m41, m42, m43, m44

执行这样一条shader指令 ”mul(vPos, g_mWorldViewProjection);” 时,如果没有做前述解决方案中的任何一条,dx则按column_major编译,将每个寄存器当作矩阵的一列。结果类似这样:
vs_3_0 dcl_position v0 // vPos<0,1,2,3> dcl_texcoord v1 // vTexCoord0<0,1> dcl_position o0 dcl_texcoord o1.xy dp4 o0.x, v0, c0 dp4 o0.y, v0, c1 dp4 o0.z, v0, c2 dp4 o0.w, v0, c3 mov o1.xy, v1
反过来如果执行了前述方案的任何一条,则dx将对对应矩阵的mul指令按row_major编译,将每个寄存器当作矩阵的一行。编译结果类似这样:
vs_3_0 dcl_position v0 // vPos<0,1,2,3> dcl_texcoord v1 // vTexCoord0<0,1> dcl_position o0 dcl_texcoord o1.xy mul r0, c1, v0.y mad r0, v0.x, c0, r0 mad r0, v0.z, c2, r0 mad o0, v0.w, c3, r0 mov o1.xy, v1 也就是同样的矩阵数据(c0、c1、c2、c3等存储矩阵的寄存器,是按照内存中数据的顺序依次填充的),同样的mul指令,由于row_major或column_major设置的不同,对寄存器的含义做了不同的解读,生成了不同的汇编代码。另外说明一下,dx默认是column_major的。这里说的例子不包括使用fx框架的情况。使用fx时,fx内部自动对矩阵参数进行了处理,所以传递矩阵时不需要转置,使用mul指令时也不需要将矩阵放到前面。

路过

鸡蛋
1

鲜花

握手

雷人

刚表态过的朋友 (1 人)

评论 (0 个评论)

facelist doodle 涂鸦板

您需要登录后才可以评论 登录 | 注册

‹‹
我的工具栏

关于我们|手机版|Archiver|开源计算机图形学社区(Open Source Computer Graphics Community) | OpenGPU Project | OpenGPU Forum (2007-2013)

GMT+8, 2017-11-25 10:02 , Processed in 0.058263 second(s), 15 queries .

Powered by Discuz! X2

© 2001-2011 Comsenz Inc.

回顶部