3D引擎中对于矩阵的使用非常多,介绍这些知识也是为了告诉开发者原理,更有助于开发者编写逻辑。

  (1)固定流水线

  各种坐标系之间的转化是通过矩阵相乘得到的,这里面就涉及到了3D固定流水线。作为3D游戏开发者,必须要知道两个流水线:一个是固定流水线,一个是可编程流水线。

  固定流水线主要原理是3D模型在屏幕上显示是按照一定得固定流程来完成的,这个固定的流程就是固定流水线。鸡蛋来说就是一个3D物体在显示器上成像的过程。

  局部坐标-->世界坐标-->观察坐标-->消隐-->光照-->透视坐标-->视口坐标-->光栅化

  物体从最初的局部坐标经过一系列的矩阵变换转换到另一个坐标系,转换矩阵中最重要的就是模型(Model)矩阵、视图(View)矩阵、投影(Projection)矩阵。首先,顶点坐标开始与局部空间,也就是局部坐标(Local Coordinate),经过世界坐标(World Coordinate),观察坐标(View Coordinate),裁剪坐标(Clip Coordinate),最后以屏幕坐标(Screen Coordinate)结束,最终目的是将物体在屏幕上展现出来。

  便于理解,总结归纳一下:

  1.局部坐标是对相对于局部原点的坐标,也是对象开始的坐标。

  2.将局部坐标转换为世界坐标,世界坐标是作为一个更大空间范围的坐标系。这些坐标是相对于世界原点的。

  3.将世界坐标转换为观察坐标,观察坐标是指以摄像机或者观察者的角度观察的坐标。

  4.在将坐标处理到观察坐标之后,我们需要将其投影到裁剪坐标上。裁剪坐标是在-1.0到1.0范围内判断哪些顶点会出现在屏幕上的。

  5.最后将裁剪坐标转换为屏幕坐标,这一过程称为视口变换(ViewportTransform)。视口变换将位于-1.0到1.0范围内的坐标转换到视口函数所定义的坐标范围内。转换的坐标将会送到光栅器中,由光栅器转换为片段。

  总体来说,就是3D建模工具导出的模型是要将起模型位置重置为(0,0,0),j将其拖放到Unity编辑器里面。在默认情况下,与世界系坐标为重合在(0,0,0)位置上。然而物体不能都堆放在世界中心点,在将其拖动到其他位置上来的这一过程就是引擎内部实现了把模型从局部坐标到世界坐标的变换,即和世界矩阵相乘得到的。接着要从程序中看到这个场景,就需要放置一个虚拟摄像机,将物体放到虚拟摄像机里面就是把物体从世界坐标转换到观察坐标,即与摄像机矩阵相乘得到的,当然后面要做消隐,就是背面消除,因为只能看到物体的正面,为了优化效率考虑背面不需要绘制出来。打上灯光让场景明亮起来,就可以通过虚拟摄像机来观察虚拟世界了。因为虚拟摄像机和人眼一样有观察距离,眼睛两侧的物体是看不到的,而看不到的物体就可以将其裁剪掉,这一过程涉及到了观察坐标到透视坐标的转换,为了方便计算将物体做投影计算。为了显示屏幕上看到,将其转化到视口坐标上。最后就是光栅化了。这样固定流水线就完成了。

  (2)可编程流水线

  硬件的发展使得显卡的运算能力得到了很大提升,也就是通常说的GPU编程。在显卡不发达是,绘制3D物体都是通过固定流水线实现的,随着显卡的提高,就有了可编程流水线。可编程流水线其实就是把CPU上进行运算搬到显卡的GPU中运算。也就是说矩阵之间的还算放到GPU中计算,可以把CPU解放出来。

  (3)平移矩阵

  在3D空间中,把一个对象从一个位置移到另一个位置,在引擎底层进行了平移矩阵换算。在3D空间中,把对象从P点移动到P‘点,运用数学公式可以计算出而二者的转化关系。

  x'=x+Tx;y'=y+Ty;z'=z+Tz

  根据这些多项式可以将它们换算成一个通用的并且可以使用矩阵表示的公式。

  

  需要注意一点的是在进行矩阵计算的时候,需要将三维的点转化为齐次坐标,进行3D计算,如果不转换,矩阵的线性变换是很难实现的,比如物体的平移变换、缩放变换等三维矩阵是无法完成的。

  向量和点都是三维的,如果使用的是点,就在点的最后再加一项1,齐次坐标就表示为(x,y,z,1)。如果是用的是向量,就在向量的最后加一项0,齐次坐标就表示为(x,y,z,0)。但是向量不可以通过矩阵换算的,点可以。在Unity中只需要拖拉就可以变换位置。

  (4)缩放矩阵

  在3D空间中对于物体的缩放并不是凭空产生的,也是经过运算得到的。运算公式为:

  x'=x*Sx;y'=y*Sy;z'=z*Sz

  上述公式可以写成矩阵换算,如下所示。

  

  在Unity编辑器的实际操作中,引擎内部就实现了矩阵的放缩,只需简单操作即可。

  (5)矩阵旋转

  在3D游戏开发中,游戏中的3D物体旋转可以通过矩阵旋转,四元数旋转,欧拉角旋转得到。矩阵旋转最基本的是绕X、Y、Z轴旋转。矩阵玄真在引擎中使用的比较多,编程时一般采用四元数或者是欧拉角实现。下面说的是绕X、Y、Z轴的旋转矩阵。

  绕X轴旋转的矩阵

  

  绕Y轴旋转的矩阵

  

  绕Z轴旋转的矩阵

  

  这些时矩阵在3D游戏中的计算方式,Unity引擎已经为开发者提供了旋转接口,函数transform.Rotate(new Vector3(0,1,0))表示绕Y轴旋转,在Rotate函数中使用了向量,它们的参数表示为x,y,z,在上述算式中y的值为1表示绕Y周迅段传,依此类推。

  

3D数学基础(三)矩阵的更多相关文章

  1. 3D数学基础:四元数与欧拉角之间的转换

    在3D图形学中,最常用的旋转表示方法便是四元数和欧拉角,比起矩阵来具有节省存储空间和方便插值的优点.本文主要归纳了两种表达方式的转换,计算公式采用3D笛卡尔坐标系: 单位四元数可视化为三维矢量加上第四 ...

  2. 3D数学基础 KeyNote 1

    [计算几何复习要点] 1.向量加法的几何含意: a+b的释意为:a的尾连上b的头,新建一条从a的尾指向b的头的向量. 2.向量减法的几何含意: a-b的释意为:尾部相连,新建一个从b的头指向a的头的向 ...

  3. 3D数学基础(四)四元数和欧拉角

    一.四元数 四元数本质上是个高阶复数,可视为复数的扩展,表达式为y=a+bi+cj+dk.在说矩阵旋转的时候提到了它,当然四元数在Unity里面主要作用也在于此.在Unity编辑器中的Transfor ...

  4. 3D数学基础(一)Unity坐标系

    Unity引擎时非常成熟的,引擎内部运用了很多的数学知识,他对开发者来说是不可见的,而且他已经封装好的算法也不是很全面.此外,要是使用引擎封装好的算法也要明白其实现的原理. 写过一些代码,也参考了一些 ...

  5. 图形与游戏中3D数学基础的说明

    1.左手坐标系与右手坐标系没有好坏之分,不同的研究领域和不同的背景下,选择不同的坐标系:传统计算机图形学采用“左手坐标系”,线性代数则倾向于使用右手坐标系 坐标系由坐标轴与坐标原点组成.原点定义坐标系 ...

  6. 3D数学基础_图形与游戏开发

    https://blog.csdn.net/popy007/article/list/2?t=1&  //向量计算相关文章 https://www.baidu.com/link?url=48C ...

  7. 【Unity3d游戏开发】Unity3D中的3D数学基础---向量

    向量是2D.3D数学研究的标准工具,在3D游戏中向量是基础.因此掌握好向量的一些基本概念以及属性和常用运算方法就显得尤为重要.在本篇博客中,马三就来和大家一起回顾和学习一下Unity3D中那些常用的3 ...

  8. 3D数学基础:3D游戏动画中欧拉角与万向锁的理解

    首先来看一下什么是欧拉角(Euler angles)?构件在三维空间中的有限转动,可依次用三个相对转角表示,即进动角.章动角和自旋角,这三个转角统称为欧拉角.——引自百度百科莱昂哈德·欧拉用欧拉角来描 ...

  9. 3d数学 7 矩阵

    7.1 矩阵-数学定义 在线性代数中, 矩阵就是以行和列形式组织的矩形数字块.矩阵是向量的数组. 7.1.1 矩阵的维度和记法 矩阵的维度被定义为它包含了多少行和多少列.一个\(r \times c\ ...

随机推荐

  1. promise知识点小结

    断断续续学习es6也有一段时间了,趁着开学空闲对知识点做一些小结. 为什么使用promise 谈到Promise,我们知道,这是社区较理想的异步编程解决方案.想要掌握promise,我们首先要知道其提 ...

  2. EF开发中EntityFramework在web.config中的配置问题

    异常: 未找到具有固定名称“System.Data.SqlClient”的 ADO.NET 提供程序的实体框架提供程序.请确保在应用程序配置文件的“entityFramework”节中注册了该提供程序 ...

  3. Linux Shell函数定义与调用

    一.Shell函数定义格式 shell函数定义格式,各部分说明如下: [ function ]等中括号括起来部分----表示可选(即可有可无) your_function_name部分----为函数名 ...

  4. Hugo + github 搭建个人博客

    前言 很早以前就有想法,搭建一个个人的博客.没有实现的原因:一方面个人的服务器不太安全掉线,欠费,维护起来麻烦,另一方面,文章编辑发布起来也不方便. 后来了解到 github 提供了博客的功能,也一直 ...

  5. Python2.X和Python3.X中Tkinter模块的文件对话框、下拉列表的不同

    Python2.X和Python3.X文件对话框.下拉列表的不同 今天初次使用Python Tkinter来做了个简单的记事本程序.发现Python2.x和Python3.x的Tkinter模块的好多 ...

  6. R语言最优化(多维)

    线性搜索的最速上升法 #### max.search <- function(f, x, y, tol=1e-9, a.max = 2^5){ if(sum(abs(y)) == 0) retu ...

  7. spring boot hello world

    本文讲解初始用户搭建spring boot 工程. 新建工程目录结构: application.java放在最外层的包目录里 先添加pom.xml的依赖包: <project xmlns=&qu ...

  8. inout口在modelsim仿真的方法

    //主要是// 和**********部分是关键 1 `timescale 1ns/1ns module tb(); reg main_clk; :] addr; reg FPGA_CS0;//FPG ...

  9. 分析logfilter+session

    1.P132分析: long before = System.currentTimeMillis(); //返回当前的计算机时间,时间的表达格式为当前计算机时间和GMT时间(格林威治时间)1970年1 ...

  10. 1 实现添加功能 1.1 定义一个学员类(Student),在Student类中定义姓名、性别和年龄属性,定义有 参数的构造方法来初始化所以的成员属性 1.2 创建学员类对象来存放学员信息,并且为每一个学生对象添加的相应的编号。并将 学员类对象添加到Map<Integer,Student>集合中 1.3 添加完成后,显示所有已添加的学员姓名 1.4 限制年龄文本框只能输入正整数,否则的会采

    学生类 package com.lanxi.demo1_3; public class Student { private String name; private String sex; priva ...