纠结和郁闷的存在感-关于DirectX与HLSL的矩阵存储方式---转载好文章
我常常这么大胆的认为,搞科学的人总是喜欢用各种让常人难以理解的复杂方式去处理某些其实可能很简单的事情,这种情况在他自身擅长的、有着诸多对手竞争的领域上极为常见。比如吧,搞DirectX的人用了左手坐标系,搞OpenGL的人偏偏就要用右手坐标系。这种情况的目的,是让他们那些搞科学的人得以突出他们的存在感和优越感。这种增加了这么多记忆成本只为了让他们爽一爽的事儿,对于我这种被科学搞了的人来说 ,就只剩下纠结和郁闷这两种感觉了。以上是某天看书看烦了的感想。
Anyway,在学习RenderMonkey的过程中,纠结于书上的各个例子无法正确实现,总是有顶点的矩阵变换出问题。最后发现是代数没学好,好吧。。。今天在看了这篇文章后,恍然大悟了很多事情,而结果又再度认证了我开篇说的那个看法:他们就是想爽一爽,让大家知道这东西是他搞出来的。。。MLGB
先复习一下线代:
1,向量与矩阵相乘的乘法中,把矩阵放在左边的叫左乘或者前乘,或者pre-multiplying。把矩阵放在右边的叫右乘或者后乘,或者post-multiplying。
2,对于矩阵的结合顺序来说,貌似是这样:左乘的时候,结合顺序是从右到左。右乘时反过来。(有待求证,我数学不好,欢迎拍砖)。
3,Row-major指的是行向量矩阵,Column-major指的是列向量矩阵。
4,数学上(注意这三个字,很重要),行向量与矩阵相乘(右乘),应该乘以一个Column-major的矩阵。矩阵与列向量相乘(左乘),应该是一个Row-major矩阵。
5,内存上(参考4),矩阵在内存里是按照一个数组来排列的,也就是说,归根结底是一唯的。怎么把矩阵这个二维的数据映射到一唯呢?可以按行优先,即先从左到右,后从上到下,一个个数下去。所谓Row-major。你也可以,按列优先,即先从上到下,后从左到右,所谓Column-major。
那么,如果,在计算机的3d世界里,它的数学上和内存上统一的话,世界就清净了。。。
问题就是,各个API都不统一,而且还很乱。MB的存在感,懂科学很了不起啊。。。。
以DirectX为例。
DirectX默认,数学上,用行向量乘以列优先矩阵来表示矩阵变换。但是,不知道哪个蛋疼的天才发明,DX的内存里存矩阵,使用行优先的方式去存的。。。。。而同为微软家的HLSL,数学上默认也是使用列优先矩阵,存储上貌似也是列优先,终于不那么蛋疼了。所以,你得这么理解,用D3DXMatirxXXXXX函数生成的矩阵,数学上是一个列优先矩阵,用行优先的方式保存在内存中。当使用ID3DXConstantTable::SetMatirx向Shader传矩阵的数据的时候,是这样,把按照行来保存的矩阵一列一列读出来,每列放到一个寄存器里,于是到了shader里就变成列优先矩阵了。。。
OpenGL呢,嘿嘿嘿,全他妈反过来。他数学上使用左乘(行向量矩阵),因为他的向量是列向量,然后存储上,却是使用列优先存储矩阵。。。。
不过,拿一个位移矩阵分别按照行优先和列优先的数学意义去验证一下,你会发现,DX和GL在存储位移分量的位置,却是惊人的统一(都是12、13、14向量表示x, y, z的偏移,具体在上面那个链接的文章里讲有,因为其实计算上错了两次,但却最后得到正确的结果,有点“负负得正”的意思)。
好极了。到了RenderMonkey。。。。
老实说,我是个偷懒的人,RM的说明书我没有仔细看,我估计它写有,但是我偷懒,于是付出了代价。
是这样,RM里手动添加的矩阵,是按照行优先的数学意义的(左乘矩阵),存储上我不知道是什么。。。。然后,shader编辑器里,默认是列优先的(右乘矩阵),搞明白这点,你的生活就没这么miserable了。
专注于Shader吧。
纠结和郁闷的存在感-关于DirectX与HLSL的矩阵存储方式---转载好文章的更多相关文章
- DirectX 9 UI三种设计学习笔记:文章4章Introducing DirectInput+文章5章Wrapping Direct3D
本文从哈利_创.转载请注明出处.有问题欢迎联系本人! 邮箱:2024958085@qq.com 上一期的地址: DX 9 UI设计学习笔记之二 第4章 Introducin ...
- hlsl 和cg 涉及 mul 左乘 右乘
error: 1. mul' implicit truncation of vector type 2. matrixXXX: array dimensions of(unknown scope en ...
- Cocos Creator 中 _worldMatrix 到底是什么(中)
Cocos Creator 中 _worldMatrix 到底是什么(中) 1. 中篇摘要 在上篇中主要做了三件事 简单表述了矩阵的基本知识,以及需要涉及到的三角函数知识 推导了图形变换中 位移 .旋 ...
- OpenBSD为何还在用CVS之感
一个轻松无聊的晚上突然想到一个问题——在当今这个Git大红大紫的时代,OpenBSD为何还在用CVS代码仓库?连他同阵营的FreeBSD都已经改用SVN,宣布逐渐废掉CVS了……问了下google,搜 ...
- 矩阵-DirectX与OpenGL的不同
http://www.cnblogs.com/graphics/archive/2012/08/02/2616017.html 矩阵是三维图形学中不可或缺的部分,几乎所有和变换相关的操作都涉及矩阵,世 ...
- DX11 Without DirectX SDK--02 渲染一个三角形
回到 DirectX11--使用Windows SDK来进行开发 目前暂时没有写HLSL具体教程的打算,而是着重于如何做到不用DirectX SDK来进行渲染.除此之外,这里也没有使用Effects框 ...
- Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 全书总结
原文:Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 全书总结 本系列文章中可能有很多翻译有问题或者错误的地方:并且有些章节 ...
- Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第二章:矩阵代数
原文:Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第二章:矩阵代数 学习目标: 理解矩阵和与它相关的运算: 理解矩阵的乘 ...
- opengl入门学习
OpenGL入门学习 说起编程作图,大概还有很多人想起TC的#include <graphics.h>吧? 但是各位是否想过,那些画面绚丽的PC游戏是如何编写出来的?就靠TC那可怜的640 ...
随机推荐
- Swift-3-字符串和字符
// Playground - noun: a place where people can play import UIKit var someString = "some string ...
- 查找出现次数大于n/k的重复元素
本文是对一篇英文论文的总结:Finding Repeated Elements.想看原文,请Google之. 这个问题的简单形式是“查找出现次数大于n/2的重复元素”.我们先从简单问题开始,然后再做扩 ...
- PowerDesigner(四)-业务处理模型(转)
业务处理模型 业务处理模型(Business Process Model,BPM)以业务需求作为出发点,用图形的方式描述系统的任务和业务流程,注重的是处理过程中数据流程.业务处理模型是从业务人员的角度 ...
- Rust: lifetime
Rust的lifetime算是它最重要的特性之一,也不大好理解,特别是官方文档的介绍有些太过简略,容易让人误解. 这篇文章: Rust Lifetimes 应该可以解答很多人疑惑,特别是有关lifet ...
- 小圣求职记A:腾讯篇
本人普通985高校计算机专业研究生一枚,从9月12号开始正式找工作,一个月过去了,参加了能参加的各个互联网公司的宣讲.笔试.面试,现用两篇随笔分享所见所闻.随笔A将以腾讯为例详细展示整个过程,随笔B将 ...
- 11gR2数据库日志报错:Fatal NI connect error 12170、
11gR2数据库日志报错:Fatal NI connect error 12170.TNS-12535.TNS-00505 [问题点数:100分,结帖人MarkIII] 不显示 ...
- URAL1018 Binary Apple Tree(树dp)
组队赛的时候的一道题,那个时候想了一下感觉dp不怎么好写呀,现在写了出来,交上去过了,但是我觉得我还是应该WA的呀,因为总感觉dp的不对. #pragma warning(disable:4996) ...
- HDU 3833 YY's new problem(换种思路的模拟,防超时)
题目链接 用p[a]保存的是输入的a在第p[a]个, 然后根据差值查找. #include<stdio.h> #include<string.h> int main() { ...
- 【剑指offer】和为S的连续整数序列
找到所有和为S的连续整数序列,序列长度>=2 我的思路:数学法,限定首元素范围,计算序列长度. 书上解法:用small和big两个游标记录序列的开始和结束位置,调整游标. 我的解法: /* 直 ...
- POJ 2182
#include <iostream> #define MAXN 8005 using namespace std; int _m[MAXN]; int main() { //freope ...