为何D3D11的几个矩阵需要转置?
在学习D3D11的时候遇到一个问题,事情是这样的:
D3D11引入了常量缓存(const buffer)用来实现 B0%E6%8D%AE">数据
// 传入shader前,确保矩阵转置,这是D3D11的要求
pMatrix->m_mxWorld = XMMatrixTranspose(pMatrix->m_mxWorld);
pMatrix->m_mxPorjection = XMMatrixTranspose(pMatrix->m_mxPorjection);
pMatrix->m_mxView = XMMatrixTranspose(pMatrix->m_mxView);
//把基本的3个3D变换矩阵放进显存去,当然对于GPU来说它是只读的,而CPU是只写的
D3D11_MAPPED_SUBRESOURCE MappedResource = {};
// 将矩阵缓冲的显存映射进来,设置矩阵数据先
HRESULT hr = g_pD3DImmediateContext->Map(g_pMatrixBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &MappedResource);
CopyMemory(MappedResource.pData,pMatrix,sizeof(ST_MATRIXBUFFER));
g_pD3DImmediateContext->Unmap(g_pMatrixBuffer, 0);
g_pD3DImmediateContext->VSSetConstantBuffers(0, 1, &g_pMatrixBuffer);
可以看到,pMatrix->m_mxWorld ,pMatrix->m_mxPorjection ,pMatrix->m_mxView 三个矩阵都是在进行了转置之后才传入常量缓存的,之后画面显示正常了。为何要转置呢?经过一番打探原来事情是这个样子的:
首先我们要知道,矩阵分为行主序和列主序两种矩阵,比如:内存中使用一个二维数组m存储矩阵,第i行第j列的表示方法分别为:
行主序:m[i][j]
列主序:m[j][i]
线性代数意义的同一个矩阵,在D3D 和OpenGL 中的存储顺序:
线代:a11,a12,a13,a14
a21,a22,a23,a24
a31,a32,a33,a34
a41,a42,a43,a44
D3D : a11,a12,a13,a14
a21,a22,a23,a24
a31,a32,a33,a34
a41,a42,a43,a44
OpenGL: a11,a21,a31,a41
a12,a22,a32,a42
a13,a23,a33,a43
a14,a24,a34,a44
D3D是左手定则,OpenGL是右手定则,另外提一句,OGRE用的也是列主序,我们发现只要把行主序和列主序的行列对调就可以了,也就是转置一下就一样了,也就是说D3D和OpenGL如果想转换的话只需要转置一下就ok,那D3D11这里为什么要转置呢,因为D3D11的constant buffer里面shader读取是列主序的读取,所以想在const buffer使用的话还是要转换成列主序,或者也可以编译shader的时候调用D3D10_SHADER_PACK_MATRIX_ROW_MAJOR这个来编译,其实效果是一样的,只不过转换做在了内部,其实早在D3D11之前GPU也是一直读取列主序的矩阵的,只不过转换在D3D驱动内部进行了而已。
或者还有一种方法就是声明这个矩阵的时候直接声明为列主序的矩阵:row_major。
还有一个方法就是在shader里面mul矩阵的时候用矩阵在前,向量在后的方法也可以:
float4 transformedPosition = somePosition * someMatrix;
float4 transformedPosition = someMatrix * somePosition;
另外还要注意const buffer的desc权限 是 cpu only write &gpu only read。
为何D3D11的几个矩阵需要转置?的更多相关文章
- C语言 矩阵的转置及矩阵的乘法
C语言 矩阵的转置及矩阵的乘法 //凯鲁嘎吉 - 博客园 http://www.cnblogs.com/kailugaji/ 1.矩阵的转置 #include<stdio.h> #defi ...
- C语言两种方式实现矩阵的转置
#include"stdio.h" typedef struct{ int i,j; int v; }Triple; typedef struct{ Triple date[]; ...
- 关于python中矩阵的实现和矩阵的转置
python中矩阵的实现是靠序列,,, 序列有很多形式, 其实矩阵是现实生活中的东西,把现实生活中的结构转换到程序中. 就需要有个实现的方法,而这种路径是多种多样的. 下面给出一个把矩阵转换成pyth ...
- C++写矩阵的转置
(2019年2月19日注:这篇文章原先发在自己github那边的博客,时间是2017年2月5日) 对于任意非n阶矩阵的转置,用c++应该怎么写代码,思考了一下,发现并没有那么简单,上网找到了一个比较好 ...
- C语言-实现矩阵的转置-随机函数产生随机数并赋予数组中-190222
//编写程序,实现矩阵的转置(行列互换). #include <stdio.h> #include <conio.h> #include <stdlib.h> ][ ...
- c++数组-矩阵的转置
#include <iostream> using namespace std; int main(){ ][]={{,,},{,,}}; ][]; ;j<;j++){ ;i< ...
- <矩阵的基本操作:矩阵相加,矩阵相乘,矩阵转置>
//矩阵的基本操作:矩阵相加,矩阵相乘,矩阵转置 #include<stdio.h> #include<stdlib.h> #define M 2 #define N 3 #d ...
- [置顶] [MATLAB技术贴]漫谈MATLAB矩阵转置
矩阵转置是matlab最基本的操作了,但这个基本操作,也是很多初学者容易出现问题的地方.本帖通过几个实例演示matlab矩阵转置的操作. 方法一:' 运算符与 .' 运算符 >>a ...
- 矩阵转置 O(1)空间
题目:用O(1)的空间实现矩阵的转置 为了方便,使用一维数组来分析.所谓矩阵转置,行变列,列变行.在转置的过程中,有的元素位置是不变的:对于变化位置的元素,要求O(1)空间完成,那么这些位置的变化一定 ...
随机推荐
- java中的volatile和synchronized
关于volatile和同步相关的东西,网上有太多错误和解释不清的东西, 所以查阅相关书籍和文章后总结如下, 如果还是也存在不正确的内容,请一定要指出来, 以免误人子弟:) 1. 原子性与可视性 原子性 ...
- jq 添加内容
向页面动态添加内容,一般用于动态网页,需要即时请求数据,并更新在页面上,使用append()更多一些,empty() - 清空所有子元素,remove() - 清除自身所有子元素. append() ...
- 《mysql必知必会》笔记3(插入、更新、删除、创建删除更新表、视图)
十九:插入数据 1:insert语句用来将行插入数据表中,可以插入完整的行.行的一部分.插入多行.插入某些查询的结果. 2:不指定列名,可以这样插入: insert into customers va ...
- Libevent:6辅助函数以及类型
在头文件<event2/util.h>中定义了许多有用的函数和类型来帮助实现可移植的程序.Libevent在内部使用这些类型和函数. 一:基本类型 evutil_socket_t 除了Wi ...
- int 和bigint差别有多大?
https://bbs.csdn.net/wap/topics/230059600 请问在mysql中int和bigint差别有多大?在什么情况下需要用到bigint? bigint 带符号的范围是- ...
- 《DL/T 976-2017 带电作业用工具、装置和设备预防性试验规程》中的样品名称及试验项目
- H5本地存储技术和微信小程序中的本地存储
1.H5的本地存储 <!DOCTYPE html> <html lang="en"> <head> <meta charset=" ...
- idea java内存分析工具
https://blog.csdn.net/qq_22194659/article/details/83829891 https://www.ej-technologies.com/products/ ...
- Java练习 SDUT-1588_圆的面积
圆的面积 Time Limit: 1000 ms Memory Limit: 32768 KiB Problem Description Give you the radius of a circle ...
- LeetCode59 Spiral Matrix II
题目: Given an integer n, generate a square matrix filled with elements from 1 to n2 in spiral order. ...