最近学习OSG到第7章观察我们的世界,与之前学习的OpenGL有一些区别,当然学OpenGL时就一直不太懂各种坐标系以及变换。看了很久,现将内容整理如下。内容来自《OpenGL编程指南》+《OpenSceneGraph三维渲染引擎设计与实践》
一、视图基础知识
计算机图形学的要点就是创建三维物体的二维图像,因为要在屏幕上显示,所以必须是二维的。我理解就是要让屏幕里的东西看起来是三维的。
但无须太早考虑如何在平面的二维屏幕上显示最终图像,要尽量在三维空间里想象物体的形状。
三维世界与屏幕像素的变换可以与照相机拍照过程类比:
(1)设置相机位置:视点变换,即观察者是从什么方向以及位置来观察物体的。
在OpenGL中是通过gluLookAt()函数来确定视图变换,这个函数的参数表示照相机的位置,朝向,以及那个方向是up方向
gluLookAt(eyex,eyey,eyez,centerx,centery,centerz,upx,upy,upz)
eye:代表了相机的位置
center代表了视线方向上任意一点,由此和eye的坐标确定了相机瞄准的哪个位置。
up:表示哪个方向是朝上的,也就是相机是正着拿还是反着拿。
在OSG中,我们使用osg::Camera节点来实现,视点变换矩阵又称为观察矩阵。Camera类保存大量的相机设置参数,如视口、投影矩阵、和背景颜色等。
(2)调整物体位置:模型变换,即选定模型位置,对场景进行安排。
对应openGL是各种transform/scal/rotate,比如物体移动旋转缩放等
在OSG中,通过使用MatrixTransform类来进行物体的平移旋转缩放等。
(3)选择镜头,调整焦距:投影变换,景物投射到二维底片的过程,这里就是把模型投射到屏幕的过程。
对应openGL就是gluPerspective/glOrtho等
在OSG中的实现就靠Camera类里的方法来定义了。
(4)冲洗照片:视口变换,将投影变换的结构反映到指定屏幕窗口
二、OSG中的坐标系
世界坐标系:即物体在那个虚拟的三维空间的位置,与OpenGL相同采用右手坐标系,但不同的是
OpenGL中:X向右,Y向上,Z向外
OSG中:X向右,Y向里,Z向上
相机坐标系(眼坐标系):(n,u,v)以眼睛为原点,
n:从参考点center指向视点eye的向量,相当与世界坐标系的Z轴。所以说从视点看向物体的方向是n负方向。
u:视点up方向和n的叉积,相当于X轴
v:是n与u的叉积,相当于Y轴
三、OSG中的模型变换
osg::Transform继承于osg::Group类,是其他所有变换类的基类。
设置空间变换节点的方法
1、直接设置空间变换矩阵的值:osg::MatrixTransform setMatrix(const Matrix& mat); const Matrix& getMatrix() const
2、直接设置变换的平移、旋转和缩放值:osg::PositionAttitudeTransform
注意,模型变换是在模型坐标,物体坐标下进行的。
当需要依次执行物体的平移、旋转和缩放操作时,不同的操作顺序会直接导致不同的运算结果,所以需要遵循SRT(Scale/Rotate/Translate)原则。
osg中继承自Transform的空间变换节点还有DOFTransform,AutoTransform,Bone等。
四、OSG中的视点变换
与模型变换相对应,可以采用视点变换改变观察点的位置和方向,即改变照相机的位置和拍摄角度,从而改变最终的拍照结果。总结模型变换和视点变换,改变观察点的位置与方向和改变物体本身的位置和方向具有等效性。
经过模型视点变换后可以将场景从世界坐标系转换到相机坐标系。
在实际编程中不用去计算相机坐标系,只要知道视点位置,视点方向以及up方向就可以确定一个相机坐标系。
OSG中使用osg::Camera节点来实现,也就是相机节点。相机节点的功能:实现视点变换,构建观察的投影矩阵和窗口矩阵,并合并为MVPW矩阵,实现三维场景向二维平面的映射并通过观察矩阵、投影矩阵和窗口矩阵的不断变化最终在计算机屏幕实现三维浏览和交互漫游需求。
五、OSG中的投影变换
投影变换相当于拍照时通过选择镜头和调整焦距等,将景物投射到二维底片的过程。投影变换的目的是产生一个视景体。
视景体有两个作用:
1、决定一个物体如何映射到屏幕(透视投影:棱台装视景体,又称视锥体;正投影:立方体,平行视景体)
2、决定哪些物体(或物体的某一部分)被裁减到最终的图像之外。
透视投影:离照相机近的物体大,离照相机远的物体小。
正投影:物体和照相机之间的距离不影响它看上去的实际大小。
六、OSG中的视口变换
将投影变换得到的结果反映到指定的屏幕窗口上去,场景最终变换到了窗口坐标系中。
总结:在OSG中以上的变化除了模型变换之外都可以由Camera类来实现。它保留了大量的相机设置参数,视口,投影矩阵,背景颜色。多个Camera节点可以共享一个子节点书结构,也就是说多台相机可以从不同角度以不同的方式拍摄同一个物体。