3D 矩阵和向量空间

基础转换矩阵:3D 基础矩阵推导 矩阵的变换是线性代数的基础,也是图形相关的技术的基础,如果做好图形渲染,仅仅了解这些基础是远远不够的。还需要比较清楚的是3D中的6次向量空间的变换的几何意义,以及变换矩阵的推导。

 

向量空间转换和顶点坐标转换的区别:其实没区别都是把顶点从一个坐标空间转换到另一个。只不过模型的转换只针对模型本身,例如模型转换到世界空间,你可以说它是从模型空间转换到世界空间,也可以说它就是模型在世界空间里面的转换,因为世界中的所有模型转换的规则并不全都一样。但是,模型从世界空间转换到视图空间就是空间坐标系的转换了,因为空间里面的所有顶点的转换规则都一样。

 

视点变换矩阵:

世界空间(World Space)转换到视图空间(Eye Space)的矩阵

 

// Lookat 表示是view转换矩阵 LH 是左手系 
// pEye 摄像机的坐标位置  pAt 前方,这也算是一个方向向量了 
// pUp 上方也是一个方向向量
D3DXMATRIX* WINAPI D3DXMatrixLookAtLH ( D3DXMATRIX *pOut, CONST D3DXVECTOR3 *pEye, CONST D3DXVECTOR3 *pAt, CONST D3DXVECTOR3 *pUp );

方法体的实现:
zaxis = normal(At - Eye)  
xaxis = normal(cross(Up, zaxis))
yaxis = cross(zaxis, xaxis)
    
 xaxis.x           yaxis.x           zaxis.x          0
 xaxis.y           yaxis.y           zaxis.y          0
 xaxis.z           yaxis.z           zaxis.z          0
-dot(xaxis, eye)  -dot(yaxis, eye)  -dot(zaxis, eye)  1

 1.pEye是视点的位置,也就是摄像机的位置,pAt是一个视角方向上的一个点,而不是描述视角方向的方向向量,这是因为

 

 zaxis = normal(At - Eye) 方法向量是通过 At - Eye 计算出来的,而不是直接为at。

2.蛋疼的是Up又是一个方向向量,因为xaxis = normal(cross(Up, zaxis)),两个向量的叉乘能够得到他们的法向量。这里利用的是up和zaxis 组成的是一个垂直的平面,而它的法向量肯定是指向xaxis x轴了。

3.cross(zaxis, xaxis)根据已知的两个轴求出第三个轴来,我这里有个疑问up难道不跟yaxis 相等吗?或许这里强调的是一种更灵活的操作,就是up它只是在yz平面上,但并不要求它与zaxis 垂直。

4.我们知道3x3矩阵只是对顶点做了相应的旋转和缩放,而-dot(xaxis, eye) -dot(yaxis, eye) -dot(zaxis, eye)则是对位置的移动,保证世界坐标的原点移动到视图坐标的原点,也就是相机的位置。

5.视点变换矩阵的获取:

 

void CameraControl::updateView()
{
	float3 up, position, lookAt;
	float yaw, pitch, roll;
	D3DXMATRIX rotationMatrix;

	position = mBean.position;
	lookAt = mBean.lookAt;
	up = mBean.up;

	pitch = mBean.angleX;
	yaw   = mBean.angleY;
	roll  = 0;
        
        // 1.根据旋转因子,获取旋转矩阵 angleX,angleY,这里不以z为轴进行旋转
	D3DXMatrixRotationYawPitchRoll(&rotationMatrix, yaw, pitch, roll);
        // 2.这里对两个方向向量进行旋转
	D3DXVec3TransformCoord(&lookAt, &lookAt, &rotationMatrix);
	D3DXVec3TransformCoord(&up, &up, &rotationMatrix);
        // 3.这个完全是因为LookAtLH的参数不是方向向量而是一个点
	lookAt = position + lookAt; 

	// Finally create the view matrix from the three updated vectors.
	D3DXMatrixLookAtLH(&mView, &position, &lookAt, &up);
}

 

透视投影矩阵的推导:

投影空间:在投影空间中,视图空间的视锥变成为一个长方体,首先这里视图空间本身是一个与世界空间一样的大空间,它也不是被截成了一个视锥。只不过转换到投影空间的,只是视图空间里的视锥部分的内容。视图空间到投影空间的转换,主要是把透视空间椎体里面的内容转换到投影空间,投影空间本身是一个矩形的。

矩形的左裁剪面为x = -1,右为x = 1,上为 y = 1,下为 y = -1,近裁剪面为 z = 0 (这里是0不是-1,这个主要是对应深度模板来的),远裁剪面为 z = 1。


从这个图可以看出P是视锥里面的一个点,而P1是映射到近裁剪面的一个点,最终P在透视空间里面的结果Pt为(P1.x,P1.y,P.z)当然还要对Pt进行缩放,使其比例为上面说道的(1,1,0),(-1,-1,-1)这个矩阵里面。

如图,现在已知Py,Pz和近裁剪面zn求P1y。 P1y/zn = Py/Pz,所以最终结果为:


又因为

 所以



 同样的可以求出



 继续求出P1z来


然后把这些式子转换成矩阵:



 视图空间转换到透视空间,做了两件事,一个是等比例缩放,把视锥缩放到一个矩形里面,然后就是调整比例,把比例调整到一个(1,1,0)(-1,-1,-1)里面。

需要注意的是:此转换没有对结果进行归一化。

// fovy 投影角度  Aspect 宽和高的比率 zn 近截面的z值 zf 远截面的z值
D3DXMATRIX* WINAPI D3DXMatrixPerspectiveFovLH ( D3DXMATRIX *pOut, FLOAT fovy, FLOAT Aspect, FLOAT zn, FLOAT zf );

屏幕空间:

从透视空间转换到屏幕空间的这个过程,是在光栅化的时候进行的,所以,你在PS里面获取到的float4 piPosition : SV_POSITION;这个顶点位置信息已经不是透视空间里的了。所以,如果想获取透视空间的position请不要使用SV_POSITION这个语义来进行描述。

 

总结:

1.在所有需要变换的内容当中,有顶点和向量之分,对于顶点来说位置的移动是有意义的,而对于向量来说,位置的移动反而会改变向量的方向。原则上来说,位置使用4x4矩阵进行转换,而向量用3x3的矩阵进行转换,因为第四行和第四列是用于平移的。

 

2.摄像机位置和方向,光源的位置和方向,是不需要进行世界矩阵变换的,因为他们本身就是身处世界空间之中。这个如果不清楚,很容易在VS里面乘一个世界转换矩阵。当然,也有特殊情况,就是你的模型够复杂,并且里面有相对模型不变的光源,这个时候光源的位置是模型空间的,那么在转换的时候是需要进行世界坐标转换的。从这里可以看出,事无绝对,最根本的还是得清楚你在干什么。

 

3.原则上来说,对于一些类似光照计算,或者其他的会用到顶点位置信息或光源,摄像机的信息的计算。都应该在世界空间,或者视角空间里面进行处理。因为这个时候,顶点之间的相对位置没有异变,放在透视空间或者屏幕空间会使结果不可控。

 

4.所有D3DX的工具方法,都是这样一个原则:1.左手系,2.顺时针为正,3.向量*矩阵。它对应了最终描述的结果。

5.在使用基础矩阵进行转换的时候:先平移,再旋转,后缩放。

6.每次转换过方向向量后,都有必要对其进行归一化。

7.通过D3DX提供的方法获取的世界矩阵,视图矩阵,透视矩阵,在shader里面转换顶点前都需要进行转置,这是我最费解的地方。不是说好了,左手系,向量*矩阵的么,为啥用的时候还需要进行一次转置呢?先这样做吧 - -。

 

 

 

 

网上的一段文字,难道方向向量,非等比例缩放也不行吗?

之前看过一些文章,说道mesh顶点的空间变换,从本地坐标系变换到世界坐标系,位置信息是乘以世界矩阵,而点的法向量要变换到世界空间下,是要乘以世界矩阵的逆矩阵的转置矩阵。网上有关于这样做的证明。只是之前在项目中,一开始我并不知道要这样做,都是乘以世界矩阵,但是用于光照方程,或者说计算球形贴图坐标的时候,也并没有出错,最后的效果都是满意的,疑惑了很久。

最近翻看《实时计算机图形学》一说,才明白其中原因。因为项目中我用到的世界矩阵中,大部分都是只包括了平移信息和旋转信息,没有去做scale的变换,都是1:1的比例在绘制。问题就在这里,因为法向量是一个方向向量,不是矢量,在变换的过程中,把法向量变为齐次坐标的时候,W分量要设置为0,也就是忽略了平移变换。所以这个世界矩阵就可以看成是一个3*3的旋转举证,而所有的旋转矩阵都是正交矩阵。正交矩阵有一个特性,就是正交举证的逆矩阵等于他的转置矩阵。所以正交矩阵的逆矩阵的转置矩阵就是正交矩阵的转置矩阵的转置矩阵,也就是正交矩阵自己(上面一段话很绕口啊)!

所以,这时候的世界矩阵的逆矩阵的转置矩阵就是世界矩阵,所以我得到了想要的结果。如果出现了scale信息,且各个轴不是1:1的比例的话。这时候的世界矩阵就不能算是正交的,就会出现问题。

Eigen库中( 旋转矩阵,变换矩阵,轴向量,欧拉角,四元数) 表示及转换 #include <iostream>#include <cmath>#include <Eigen/Core>#include <Eigen/Geometry>using namespace std;int main ( int argc, char** argv ){    cout << "hello-----" <&lt 阅读详情

相关推荐

【OpenGL】5 3D游戏数学基础:向量矩阵运算与MVP坐标空间变换系统

3D游戏开发的核心在于数学,而矩阵向量运算则是这座大厦的基石。本文作为Python游戏开发OpenGL系列的第五篇,将系统讲解3D图形学中的数学基础:从向量的点积叉积到矩阵的变换复合,从模型-视图-投影(MVP)矩阵的构建原理到各坐标空间(模型空间、世界空间、视图空间、裁剪空间、NDC、屏幕空间)的转换流程。我们将从零实现一个完整的3D数学库,包含Vector3Matrix4类,涵盖平移、旋转、缩放、LookAt、透视/正交投影等核心功能。针对数学编程中常见的矩阵乘法顺序混淆、法线矩阵计算错误、欧拉角万

nmdbbzcl的博客 397

3D数学读书笔记——3D中的方位与角位移

关于3D中的方位与角位移的相关知识

睿不可挡的专栏 2723

5、数学与图形概念:向量矩阵空间变换详解

本文详细介绍了数学与图形学中的核心概念,包括向量的模、单位向量、点积与叉积,矩阵的基本运算及特殊矩阵的应用。同时,文章深入探讨了空间变换的全过程,从局部空间到世界空间、视图空间以及投影空间的转换,并结合GLM库OpenGL的实际使用进行代码示例。通过理论与实践相结合,帮助读者掌握3D图形编程的数学基础,为构建复杂3D场景打下坚实基础。

vv45678的博客 159

3D数学基础——矩阵变换

3D数学基础——矩阵变换 0. 前提假设与符号定义 向量矩阵 假设向量kkk右向量hhh变换得到: 设向量h=[x,y,z]Th=[x,y,z]^{T}h=[x,y,z]T 设向量k=[u,v,w]Tk=[u,v,w]^{T}k=[u,v,w]T 3维矩阵M3×3=[m11m12m13m21m22m23m31m32m33]M_{3×3}=\begin{bmatrix} m_{11} & m_{12} & m_{13} \\ m_{21} & m_{22} & m_{23}

暴雨梨花博客 2145

Unity 矩阵简介

由于矩阵算法的问题涉及面很广,本文只展示单独的平移、旋转缩放矩阵,让小伙伴们对矩阵有一个直观的认识,消除陌生感。

m0_63024355的博客 1385

三维空间几何变换矩阵

继之前的http://blog.csdn.net/piaoxuezhong/article/details/62430051绕轴旋转,这里汇总了一下三维空间中的平移变换,比例变化,旋转变换等数学知识: 基本三维几何变换 1. 平移变换 若空间平移量为(tx, ty, tz),则平移变换为              2. 比例变换 (1) 相对坐标原点的比例变换

满城风絮 2万+

[Unity] 3D数学基础 - 坐标系、向量矩阵

一、坐标系 模型坐标系: 物体自身的坐标系,只描述自身各个顶点的情况。 在3D模型坐标系中,z方向前向如果是负值,我们称为右手坐标系,如果是正值,我们称为左手坐标系。在3DMax中使用了右手坐标系,Unity使用了左手坐标系。 世界坐标系: 系统的绝对坐标系,在没有建立用户坐标系之前画面上所有点的坐标都是以该坐标系的原点来确定各自的位置的。 摄像机坐标系: 摄像机坐标...

weixin_33898233的博客 617

3D空间中的旋转:欧拉角,旋转矩阵,四元数,旋转向量

一般用一个齐次矩阵表示位姿,即同时表示旋转平移。MATLAB中的转换函数% 已知按顺序绕n系下x,y,z轴旋转对应角度后得到b系% 即描述物体在n系下的姿态角(角标描述先下后上)% 欧拉角→方向余弦% 欧拉角→四元数% 方向余弦→欧拉角% 方向余弦→四元数% 四元数→方向余弦% 四元数→欧拉角。

保持分享欲 2366

SharpDX数学库详解:向量矩阵3D空间计算实战

SharpDX是一套功能强大的.NET框架,为开发者提供了高效的DirectX API封装。其中,SharpDX数学库(位于Source/SharpDX.Mathematics目录)是游戏开发图形编程的核心组件,提供了向量矩阵四元数等基础数学结构,帮助开发者轻松处理3D空间计算问题。本文将带你深入了解SharpDX数学库的核心功能,掌握向量运算、矩阵变换3D空间计算的实战技巧。 ## S

gitblog_00753的博客 785

3D图形学与可视化大屏: 向量矩阵运算是什么,都有哪些知识点。

本人是10年经验的前端开发UI设计资深“双料”老司机,1500+项目交付经历,带您了解最新的观点、技术、干货,下方微信我可以我进一步沟通。

2401_87844866的博客 976

镜像矩阵的运用(javascript)

1、定义镜像矩阵 2、以下是镜像矩阵的展开 3、2维度空间3维空间的镜像矩阵的表达式,首先是2维空间,对于2-D空间的某个条直线做镜像,假设该直线的单位法向量u(x,y),由计算得到2-D空间的镜像矩阵: 对于3-D空间的某平面做镜像: 4、项目中的代码实现(3D空间) /** * 计算镜像矩阵 * * @param { Vector3 } v3 归一化向量(通常是面法向量) * @returns { Matrix4 } 镜像矩阵 */ export const calculationR

苹果蜀黍与福尔猫斯 1950

HarmonyOS 6 ArkGraphics 3D精讲:坐标、向量矩阵——初识3D数学的“空间建模”

本文深入讲解HarmonyOS 6 ArkGraphics 3D中的3D数学基础,重点解析坐标、向量矩阵3D空间建模中的核心作用。文章通过太阳-地球-月亮公转自转模型案例,直观展示父子节点层级变换的传递机制,阐明局部坐标与世界坐标的转换关系。同时详细介绍了右手坐标系规则、向量运算的实际应用(如光照计算中的点乘运算),以及相机视图矩阵的工作原理。全文强调3D数学不是炫技工具,而是解决实际开发问题的必备基础,帮助开发者理解节点变换、相机定位等核心概念,为后续Shader编写打下坚实基础。

weixin_50077637的博客 801

DirectX12(D3D12)基础教程三 线性代数与3D世界空间

向量最基本的定义就是一个如图坐标点(3,4)根据可以计算出它是5=。是与X轴的夹角θ,向量的长度方向根据坐标可以计算出,通常书写标记为:通常大家喜欢在字母上面加一横表示向量,如:。有一个特殊类型向量的模(长度)等于1叫做单位向量,把一个向量变成单位向量这叫。任意向量的每个分量除以向量的模就得到它的单位向量。特别是在我们只关心方向不关心模(长度)的时候。比如要标准化,先计算模,然后除以向量的模 ,的单位向量。现在我们再计算向量的模,再次证实了。

962

空间坐标乘旋转矩阵_向量坐标转换、旋转矩阵以及视图转换

3d世界中,我们需要不停的在各个空间里面转换坐标,比如把物体由模型空间转化到世界空间,把世界空间中的点转换到摄像机的视图空间。我们知道,坐标转换可以用向量与一个转换矩阵相乘来达到转换目的。但要注意的是如果选择的是行向量,则是矩阵放在右边相乘,如果是列向量,则需要把矩阵放在向量左边相乘。如果不考虑位移,则我们可以用一个3X3矩阵来表示旋转或者缩放操作。如果我们用行向量来表示某个模型空间中的某个点p...

weixin_39849894的博客 1885

向量坐标与旋转矩阵

3d世界中,我们需要不停的在各个空间里面转换坐标,比如把物体由模型空间转化到世界空间,把世界空间中的点转换到模型空间。我们知道,坐标转换可以用向量与一个转换矩阵相乘来达到转换目的。但要注意的是如果选择的是行向量,则是矩阵放在右边相乘,如果是列向量,则需要把矩阵放在向量左边相乘。如果不考虑位移,则我们可以用一个3X3矩阵来表示旋转操作。 如果我们用行向量来表示某个模型空间中的某个点p(px py pz),假设模型经过旋转后,新的轴在世界空间中表示为 r(表示左右轴),u...

chun_888的博客 766

切线空间(TBN) ---- 聊聊图形学中的矩阵运算

本文没有详细讲解切线空间的来源推导过程,更无法详细讲解矩阵的意义运算。所以肯定需要一些预备知识。 先说说矩阵运算:列主矩阵向量(或者点)乘在右侧。若是用正交的三个坐标轴来构成一个矩阵的旋转部分,姿态矩阵每个坐标轴对应一列,物体空间的变换矩阵则每一个坐标轴对应一行。对...

chishanxu3325的博客 5498

Direct3D入门-向量距阵变换

向量就是包含大小(长度)方向的一个量。向量有2维的,也有3维甚至4维的。在DX的所有结构体中,有一个结构体是用来表示3维向量的,它就是D3DVECTOR,这个结构体很简单,只有三个成员:x、y、z。一般来说,如果不涉及到向量运算的话,用这个结构体来定义一个向量就可以了。我们可以它来表示方向以及顶点在3D世界中的位置等。如果你要对那些向量进行一些运算的话,使用D3DVECTOR就很不方便了,因为在

microsoftwin32的专栏 1053

Unity3d 三维空间向量矩阵

Vector3:  Unity3D中Vector3类定义(只写有用的):  属性:  x,y,z                表示一个空间向量。  this                       用于访问x,y,z三个数据使用数组的方式访问,比如[0][1][2]  normalized            返回单位化向量后的值(只读)。单位化向量是个很重要

互动教程网[www.hdjc8.com] 6234

3D数学 ---- 矩阵的更多知识(4)

4D向量4x4矩阵不过是对3D运算的一种方便的记忆而已。 4D齐次空间 4D向量有4个分量,前3个是标准的x,yz分量,第4个是w,有时称作齐次坐标。 为了理解标准3D坐标是怎样扩展到4D坐标的,让我们先看一下2D中的齐次坐标,它的形式为(x, y, w)。想象在3D中w=1处...

chubaisheng8627的博客 108
上一篇: 3D 基础矩阵推导
下一篇: 反射(Reflect)和折射(Refract)
lengbingteng
博客等级 码龄18年 25粉丝 153原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值