3d数学基础学习总结

来源:互联网 发布:linux进程间通讯方式 编辑:程序博客网 时间:2024/06/07 01:08

3d数学基础目录

第1章 简介
  1.1 什么是3D数学
  1.2 为什么选择本书
  1.3 阅读本书需要的基础知识
  1.4 概览
  第2章 笛卡尔坐标系统
  2.1 1D数学
  2.2 2D笛卡尔数学
  2.3 从2D到3D
  2.4 练习
  第3章 多坐标系
  3.1 为什么要使用多坐标系
  3.2 一些有用的坐标系
  3.3 嵌套式坐标系
  3.4 描述坐标系
  3.5 坐标系转换
  3.6 练习
  第4章 向量
  4.1 向量——数学定义
  4.2 向量——几何定义
  4.3 向量与点
  4.4 练习
  第5章 向量运算
  5.1 线性代数与几何
  5.2 符号约定
  5.3 零向量
  5.4 负向量
  5.5 向量大小(长度或模)
  5.6 标量与向量的乘法
  5.7 标准化向量
  5.8 向量的加法和减法
  5.9 距离公式
  5.10 向量点乘
  5.11 向量叉乘
  5.12 线性代数公式
  5.13 练习
  第6章 3D向量类
  ……
  第7章 矩阵
  第8章 矩阵和线性变换
  第9章 矩阵的更多知识
  第10章 3D中的方位与角位移
  第11章 C++实现
  第12章 几何图元
  第13章 几何检测
  第14章 三角网络
  第15章 图形数学
  第16章 可见性检测


========


3D数学基础_01

http://blog.csdn.net/eclaix/article/details/6366878


在进行3D编程的时候, 需要知道一些基础的数学知识. 我做了一些整理, 希望对大家有用. 因为只是一


些重点的整理, 很多内容不是连续的. 如果希望更进一步的理解, 还是去看相关图形学的书比较好.
 
1:  3D游戏渲染的原理.
2D游戏的图像很容易理解, 一副副图片以各种方式排列在一起就OK了.
3D游戏的图像稍微复杂一些:
首先需要使用数学方法构建一个世界. 这个世界不是真实存在的, 而且也不是直接可见—因为它们就是


一对数字. 然后选取观察点(Camera)和观察窗口(视窗), 根据各种数学方法, 计算出从观察点(camera)


应该看到的图像. 然后显示出来.


渲染结果: 从相机这一点看到的图像—当然, 它们不是真实存在的, 而是计算得出.
 渲染结果
 
2: 屏幕坐标系(2D)与3D坐标系
首先是屏幕坐标系. 计算机的显示屏幕是2D的. 不管玩的是2D游戏, 还是3D游戏.
而且需要注意的是, 屏幕坐标系中左上脚为原点(0, 0). 向右, 向下延伸. 在做GUI相关编程时需要注意


这一点.
  
之后是3D坐标系. 首先3D坐标系与2D坐标系有一个重要的不同, 就是有两个3D坐标系: 左手坐标系和右


手坐标系.
(而2D坐标系只有一个: 不管将2D坐标系画成什么样子, 总可以根据旋转, 将它们重合. 也就是所有2D坐


标系都是等价的. )


可以看到, 左手坐标系不管怎么旋转, 都不可能与右手坐标系重合. 但是左手坐标系之间, 或者右手坐


标系之间是等价的. 所以3D的世界中有两种坐标系. 它们之间没有任何优劣之分. DirectX使用左手坐标


系, OpenGL和OGRE中使用右手坐标系. 搞错坐标系的话, 会出现位置不对等奇怪现象, 需要注意.
  
3: 多坐标系
游戏编程中, 最常见的有三种坐标系: 世界坐标系, 物体坐标系, 相机坐标系. (还有一个是惯性坐标系


, 游戏中不常用, 就不提了.)
A: 世界坐标系描述的是绝对位置, 也叫作全局坐标系或者宇宙坐标系. 
对应Global Position.
 B: 物体坐标系是以某个物体的中心为原点的坐标系.
对应Local Position
    一般物体自转的话, 一定要在物体坐标系中作.
 C: 相机坐标系. 相机坐标系就是以相机为原点的坐标系. 其实它是一个特殊的物体坐标系. (相机也是


一个物体)
    另外, 左手坐标系中, +Z为观察方向; 右手坐标系中 –Z为观察方向.
    在手动计算位置(各种Debug)的时候, 非常重要.
为什么要引入这么多坐标系? 其实就是为了处理简单. 具体原因的话参考相关书籍, 使用中记住有这么


三种重要的坐标系就OK了.


4: 向量, 矩阵与变换
向量&矩阵的定义和运算, 请参考线性代数教科书.
这里主要介绍3D引擎中经常出现的4D矩阵.
它的写法是:


其中的R代表旋转部分, T代表平移部分. 旋转的R部分比较复杂,请参考专业书籍; T的换比较简单X,Y,Z


分别代表在X轴, Y轴, Z轴上的平移量.
如果在3D引擎中看到一个4*4矩阵, 那么很大的可能是以上形式的矩阵.
 
3D引擎中的变换主要包括平移, 旋转, 缩放, 投影, 镜像变换等. 其中投影又包括正交投影和透视投影.
 
5: 方位(Orientation)与角位移
3D引擎中处理最多的, 应该就是平移与旋转了. 上边的4D矩阵定义中也可以发现, 就有2块: 旋转和平移


. 平移的话比较简单, 沿着X, Y, Z移动的量构成了这个物体在3D空间中的平移. 旋转的话, 就非常复杂


了. ( 至少我这么想-_-)
首先, 需要明确一下概念: 方向(Direction)与方位(Orientation).
一开始可能比较难区分这两个概念…..其实搞清除了也简单, 方位(Orientation)是方向(Direction)加


自转.
 
两架飞机. 它们都沿着同一个方向飞行. 假设是北(N).
它们的方向虽然相同, 但它们的方位不同. 第二架飞机相比第一架飞机, 自转了90度.
 
方位的概念.
描述物体位置时, 必须指定一个原点, 位置是相对于原点的偏移量.
同样, 描述方位时, 也必须指定一个已知方位(起始方位), 相对已知方位的旋转的量就是这个物体的方


位. 这个旋转的量叫做角位移.
(概念上虽然不同, 角位移的值与方位的值时一样的. 类似与偏移量与位置的关系)
3D引擎中有三种方法表示方位: 矩阵, 欧拉角, 四元数.
通常情况下, 用矩阵和四元数表示角位移(用于计算); 用欧拉角表示方位(用于人来查看).
(这部分十分绕, 反正我理解的时候累死了无数脑细胞…大家慢慢琢磨吧)
 
A: 欧拉角
   要想知道一个物体的方位, 那么只要知道它与X, Y, Z轴之间的夹角就可以了.
对人来说, 这是最直观也是最简洁的方式. 相对于各个轴的夹角被命名
为Roll-Pitch-Yaw. (也有一种Heading-Pitch-Bank的命名法, 不过与惯性坐标系相关,
于是忽略掉)
   Roll(Bank)                                  与Z轴的夹角
Pitch                                                        与X轴的夹角
Yaw(类似Heading)       与Y轴的夹角
欧拉角优点是简洁(只有三个数), 便于人理解; 但缺点是不方便计算.
于是有了以下两种表示方法.
 
B: 矩阵
   矩阵数字最多, 3*3一共9个. 概念也比较简单, 直接作乘法就可以了.
但缺点就是需要存储的数字多.
 
C: 四元数
   个人以为这个是最难理解的概念之一… 但是它的优点就是比较简洁(四个数),
而且便于计算, 尤其是插值运算. 四元数的诞生还有一段有趣的小故事,
有兴趣的同学可以趣看看.
 
   一个四元数包括一个标量分量和一个3D向量分量. 一般记为[w, v] = [w, x, y, z].
   四元数通过以下方式应用于3D引擎中.
   首先是概念基础: 一个旋转序列(也就是很多个旋转)等价于一个单个旋转. -> 也就是
任何角位移都能表示为 绕单一轴的单一旋转. 这个轴叫做旋转轴, 它可以是任意方向.
然后是四元数记法: 设 n 为旋转轴, a 为旋转角, 那么四元数
Q = [ cos(a/2), sin(a/2)*n ] = [ cos(a/2), sin(a/2)*nx, sin(a/2)*ny, sin(a/2)*nz ]
注意, 角的值a与轴的方向x,y,z都没有直接出现. 都经过了三角函数的换算.
(这样作是为了方便插值运算, 不过…嗯, 随便吧, 写一遍都觉得累. 至少知道里边的
值是经过三角函数变换的. 如果直接拿出来当角度值, 那就窘了.)
另外, 只用单位四元数(模为1)来表示方位.
 
这三种表现方式之间是可以互相转换的. 给一个最简单的: 四元数到欧拉角
Pitch角    = asin(-2(yz + wx))
Yaw角    = atan2(xz – wy, 1/2 – x^2 - y^2)  cos(pitch角) != 0
               = atan2(xz – wy, 1/2 – y^2 - z^2)  cos(pitch角) == 0
Roll角     = atan2(xy – wz, 1/2 – x^2 - z^2)  cos(pitch角) != 0
               = 0  cos(pitch角) == 0
 
其他n长的转换公式大家自己找图形学书. 其实看看就行, 知道有这么回事儿就可以. 在图形引擎中已经


将这些东西都实现好了. 一般还是会用是最终目标.
========

3D数学基础_02



6: 几何图元
几何图元就是指点, 线, 面, 体之类.
这个没什么特别好说的. 主要需要注意两个缩写:
AABB和OBB. 它们都是指矩形边框,
AABB指 axially aligned bounding box.  沿着坐标轴的矩形框
OBB 指 oriented bounding box. 任意方向的矩形框
(作几何检测的时候, 有时候按照AABB和OBB分成两类. 知道是什么东西就可以, 别被缩写骗了. 不知道


是什么的时候, 觉得玄乎玄乎还挺神秘的, 知道了以后, 原来就是四方块…)
几何检测的几种方式。其中的(a),(b),(c)比较常用。


7: 3D模型


3D模型主要包括三类: 多边形网格模型, 曲面模型和离散模型. 其中, 在游戏中应用最广泛的是多边形


网格. 而由于OpenGL和Direct3D都使用三角形为最基本的图形单元, 所以我们只讨论三角形与三角网格.


一组相连的三角形称为三角网格.


3D数学中三角形有正面和反面, 并且拥有一条法线. 三角形的正面是其法线伸出的方向.


三角形的优点:只有三个顶点且不可被拆分. 一个三角形一定处于同一个平面中. 其他多变形都可能处于


不同平面. 所有其他多边形都可以使用三角形来表示.


 三角形顶点的顺序十分重要. 而且左手坐标系和右手坐标系中, 它们的顺序也不尽相同. 如果手动指定


了3个顶点, 但是没有显示对应的三角形. 那么很有可能是它们的顺序不对. 这时候你需要确认一下系统


的坐标系和顶点的位置和顺序.


 
三角网格中因为存在大量重复使用的顶点, 所以一般常用索引三角网格方式来进行描述.


在索引三角网格中, 需要维护两个列表: 顶点(Vertex)表和三角形的索引(Index)表.


其中:


  A: 每个顶点必须包括一个3D位置. 可选包括纹理坐标, 表面法向量, 光照值等可选数据.


  B: 三角形索引表包含构成三角形的索引. 所以索引是三个一组出现.
  
这是一个普通的立方体模型. 它有8个顶点和6个面. 每个面都是四方形, 一个四方形由2个三角形构成. 


所以它有12个三角形.


如果采用纯顶点方式, 那么它需要保存 12 * 3 = 36个顶点数据.


如果采用索引三角网格方式, 那么它需要保存8个顶点, 36个索引. 之后的文章中我会介绍典型的顶点和


索引定义. 通常索引只是一个4字节整数, 而顶点可能包含多个数据(一般超过20个字节). 那么, 在渲染


时, 动则需要向GPU传递几万个点信息的情况下, 使用索引是非常经济的选择.


8: 一个典型的图形管道


最后, 介绍一个典型的现代图形管道(pipe line).


主要通过数据流来介绍管道的各个部分.


这只是一条理论上的管道, 之后会介绍DirectX9的缺省pipe line(一个具体的例子.)


当然, 大家会发现, 它们之间还是非常相似的.


  A: 建立场景. 在开始渲染之前, 首先需要设置整个场景. 比如相机的位置, 方向. 视锥(可视范围), 


环境光照, 雾化参数. 渲染的输出—视图窗口等.


视锥 
 
  B: 可见性检测. 当选定好相机, 指定了视锥参数以后, 就可以决定那些物体是可见的, 那些是不可见


的. 根据这些信息, 我们可以去掉那些不可见的物体. 因为计算并渲染看不见的东西是在浪费时间.


  C: 设置物体的渲染状态. 主要是物体的纹理属性.


  D: 几何体的生成与提交. 这一步是向3D API提交几何体. 通常提交的数据是各种三角形或者三角网格


.


  E: 变换与光照. 几何体数据传递完成之后, 就可以计算顶点光照. 通常有四种形式的光: 环境光, 直


线光, 点光, 锥形光. 物体上可以漫反射, 镜面反射照射过来的光线. 物体也可以自发光. (通常自发光


的属性在物体材质中设置.)


点光
直线光
直线光
 
探照灯形光
锥形光
   
  F: 背面剔除与裁减(3D). 背对相机的面会被剔除(背面剔除). 因为它们不可见. 三角形在视锥外的部


分也会被剔除, 同样因为它们不可见. 这是3D空间中的裁减. 不过这种裁减可能导致多边形出现.
  G: 投影到屏幕空间与裁减(2D) 之后, 3D世界中的几何体会被投影到2D屏幕空间中. 之后, 屏幕显示


范围以外的部分会被裁减掉(2D裁减). 这种裁减相比之下简单易行. 但是必须在投影运算之后进行。
 
  H: 光栅化. 当完成多边形到屏幕的转换之后, 就进入光栅化阶段. 光栅化指根据投影过来的几何信息


, 那些象素需要被绘制. 很多图形学的核心算法在这里体现. 比如抗锯齿等. 不过因为大多是硬件实现, 


所以这里不具体讨论. 只要知道它是一个很复杂且重要的过程即可. 


数学世界中的图形 转换到 屏幕上的像素点
 
  I: 象素着色. 最后, 在图形管道的最后阶段, 计算各个象素的颜色值. 这个过程叫做着色.材质的颜


色, alpha混合, 深度buffer都在这里应用. 而且在现代显卡上, 这一步是可以编程的. DirectX中叫做


Pixel Shader, OpenGL中叫做Fragment Shader. 它们中可以包含一些复杂的算法. 而现在各种华丽的效


果基本都通过它们实现. 比如HDR, 卡通渲染等等.
 
一个HDR和卡通渲染出来的茶壶. 可以虽然是同样的模型, 但他们的表现方式却可以千差万别.而这都是


通过着色来实现的.
另外, 学习3D的人应该已经发现, 茶壶是出现频率非常高的一种物体, 基本快赶上立方体了… 不知道大


家有没有想过原因?:)
========
0 0
原创粉丝点击