最近在开发项目的时候,常常用到Three.js,用起来很方便。可是,当引擎迭代升级的时候,以前的很多的技巧,并不一定使用最新的引擎。我认为应当对底层的原生API有很深入的认识并掌握3D开发相关的数学知识才能成为一个合格的3D开发人员。最近在参与编辑WebGL2.0的书籍,也趁着这个机会好好学习下计算及图形学。
今天对变换流程做一个简单的概述,后面的博客我将会和我的同学一起为大家结合线性代数和计算机图形学来讲解每种变换矩阵的推导。
在《WebGL编程指南》序中,有一句话我非常喜欢,并分享给大家:
接下来,我们来看一下WebGL中的变换流程,或者说是Opengl es 3.0中的变换流程(以下图片来源自网络):
1.模型变换及模型矩阵
局部(物体)坐标系或者局部(物体)空间:
物体空间比较容易理解,就是需要绘制的3D物体所在的原始坐标系代表的空间。例如在进行设计时,物体的几何中心是摆放到坐标系原点的,这个坐标系代表的就是物体空间。
世界坐标系或者世界空间:
世界空间也不难理解,就是物体在最终3D场景中的摆放位置对应的坐标所属的坐标系代表的空间。
模型变换指的是将物体坐标系下的物体变换到世界坐标系下。模型变换通过乘以模型矩阵来实现。模型矩阵包含这平移,旋转,缩放的信息。模型矩阵也可以称作基本总变换矩阵。
我们需要注意的是:模型变换针对是整个局部坐标系,或者说同一局部坐标系下的所有物体,或者说所有坐标。
2.视变化及视图矩阵
摄像机坐标系或者摄像机空间:物体经摄像机观察后,进入摄像机空间。
视变化,是将世界坐标系下的坐标变化到摄像机坐标系,视变换是通过乘以视图矩阵实现的。
首先,我们要知道视并不存在真正的摄像机,只不过是在世界坐标系里面选择一个点,作为摄像机的位置。然后根据一些参数,在这个点构建一个坐标系。然后通过 视图矩阵将世界坐标系的坐标变换到摄像机坐标系下。
WebGL成像采用的是虚拟相机模型。在场景中你通过模型变换,将物体放在场景中不同位置后,最终哪些部分需要成像,显示在屏幕上,主要由视变换和后面要 介绍的投影变换、视口变换等决定。其中视变换阶段,通过假想的相机来处理矩阵计算能够方便处理。对于WebGL来说并不存在真正的相机,所谓的相机坐标空 间(camera space 或者eye space)只是为了方便处理,而引入的坐标空间。
基于WebGL 2.0的视图矩阵推导:https://blog.csdn.net/weixin_37683659/article/details/79830278
3.投影变换及投影矩阵
剪裁坐标系或者剪裁空间:并不是摄像机空间中所有的物体都能最终被观察到,只有在摄像机空间中位于视景体内(投影范围内)的物体才能最终被观察到。因此,将摄像机空间内视景体内的部分独立出来经过处理后就成为了剪裁空间。
投影变换是将摄像机坐标系下的物体变换到剪裁坐标系,投影变换是通过乘以投影矩阵实现。
投影方式有两种,一种是正交投影,一种透视投影。
正交投影:投影到近平面上相同尺寸大小的图形大小相同,不会有真实世界那种近大远小的感觉。
透视投影:同样尺寸的物体,近处的物体投影出来大,远处的物体投影出小,会产生与真实世界一样近大远小的感觉。
在乘以投影矩阵后,任何一个点的坐标[x,y,z,w]中的下x,y,z的分量将在-w~w内。
4.透视除法
标准设备坐标系或者标准设备空间:对剪裁空间执行透视除法后得到的就是标准设备空间了,对于WebGL而言标准设备空间3个轴的坐标范围都是-1.0~1.0。
从剪裁坐标系到标准设备坐标系的变换是通过执行透视除法来完成的。所谓透视除法其实很简单,就是将齐次坐标[x,y,z,w]的4个分量都除以w,结果为[x/w,y/w,z/w,1],本质上就是对齐次坐标进行了规范化。
需要指出,剪裁空间之后的变换就不归开发人员管了,是由管线自动完成的。包括透视除法以及后面的视口变换。
6.视口变换
屏幕坐标系或者窗口空间:实际窗口空间也很容易理解,其一般代表的是设备屏幕上的一块矩形区域,用于呈现渲染结果,其坐标以像素为单位。
视口变换是从标准设备坐标系到屏幕坐标系变换,主要工作是将执行透视除法后的X、Y坐标分量转换为屏幕坐标系的XY像素坐标。主要的思路是将标准设备空间的XY平面对应到视口上,将-1.0~1.0范围内的X、Y坐标折算为视口上的像素坐标。当然,这个部分也是由管线自动完成。视口范围仅需要调用glViewPort这个函数进行设置即可。
7.总结
这里只是做了一个变换流程简单的概述,哪里写的不好,请多指教。