本篇会介绍openGL中的变换和坐标系统,由于篇幅的问题,本篇文章不会把重点的笔墨放在数学基础,如果对数学概念有疑问的读者可以翻一下大学的线性代数教材。
首先是向量的概念,向量是既有大小又有方向的量,他可以用带箭头的线段形象的表示,在openGL中,向量在计算光照上有非常大的作用,这点后面的文章会详细介绍。需要注意的是,在openGL中我们提到的向量常常是标准化向量,那什么是标准化向量呢,就是长度为1的向量,在shader中,我们用自带的函数对向量进行标准化。
vec3 norm = normalize(Normal);那标准化有什么好处呢,这里有一个例子,向量点乘的结果是向量大小的乘积乘以向量夹角的余弦,如果向量都是标准化的,那么向量的点积就直接得到向量夹角的余弦了,这在计算光照时会很有用。
下面一个概念就是齐次坐标的概念,我们一般用三维的点来表示三维空间,但是我们会在shader中经常看到如下的操作:
vec4(position,1.0f)为什么偏偏要给自己加上一个数呢?为什么是1呢?这里就涉及到了齐次坐标的概念,齐次坐标就是把原来n维的坐标用n+1维表示,齐次坐标是计算机图形学的重要手段之一,它既能用来明确区分向量和点,同时也更容易进行线性变换,由于图形硬件已经普遍支持齐次坐标和矩阵除法。
在介绍变换前,还有一个概念就是矩阵,矩阵是一个按照长方阵列排布的复数或实数的集合,在openGL中,矩阵常常被用来表示变换,因为向量也是一个单列矩阵,所以它和矩阵的乘积,结果就会是经过变换后的矩阵,所以在shader中,我们经常也会看到如下的运算:
gl_Position = projection * view * model * vec4(position,1.0f);
注意,矩阵的乘法满足结合律不满足交换律,这点要格外注意,所以前三个矩阵经常会先结合成一个矩阵,但是相乘的顺序不会改变
接下来就是用矩阵表示变换,首先是缩放:
然后是旋转:
第一个矩阵是沿x轴旋转,注意,旋转的定义有个旋转轴的概念,那么不沿xyz轴的旋转如何定义呢,由于一些问题(万向节死锁),经常用四元数表示,具体可以参考这篇文章:http://www.cnblogs.com/soroman/archive/2008/07/15/1118996.html
到这里,似乎不需要所谓齐次坐标,我们忘记了平移,3*3的矩阵是不能表示平移3维向量的,只能这样平移:
我们找到了使用齐次坐标的原因,那为什么旋转缩放也要这样表达呢?因为坐标转换通常不是单一的,一个几何体的每一帧都设计了多个平移旋转缩放,为了减少计算量,通常是先把这些矩阵串接后得到一个最终变化的矩阵,所以所有变化矩阵都要统一。
另外一个需要使用齐次坐标的原因是因为,当最终进行视口变换时,要进行透视变换,透视变换时就用最后一个分量分别除前三个变量就变换回来了。
关于齐次坐标最后一个需要说明的就是,我们通常用(x,y,z,1)表示点,用(x,y,z,0)表示向量,原因之一是两个点只差就是向量,另一方面,向量就是表示方向的,平移没有意义,理论上等比缩放也是没有意义的,但是不等比缩放就会改变向量了。
下一篇将结合cocos2d-x的代码介绍摄像机,基础知识就差坐标轴的介绍了,关于坐标轴,掌握如下几个坐标轴的概念就可以了:
这就是几个坐标系在整个渲染过程的变换,经历三次矩阵变换,这就是著名的MVP矩阵的由来(它和最有价值球员半毛钱关系都没有)。
本地坐标空间(local space):在建模软件中的坐标空间,物体本身的坐标空间。
世界坐标空间(world space):将所有模型摆放到一个世界空间中,这个模型在空间中的坐标。
观察坐标空间(view space):即摄像机范围空间
裁剪坐标空间(clip space):将不在摄像机范围内的模型裁剪出去后的空间
屏幕空间坐标(screen space):最终显示在屏幕上的坐标空间。
下一篇将介绍MVP矩阵,将详细介绍MVP矩阵的由来和它们是如何完成这些变换的。
能力不足,水平有限,如有错误,欢迎指出。
原文链接:https://www.f2er.com/cocos2dx/339605.html