pigsir请进,关于透视投影

zhangyan_qd 2002-08-01 11:12:02
首先,如果没有特殊需要,请忘记屏幕像素这回事。屏幕就是一个观察窗口,所有真实世界的东西都是以逻辑单位画出来的。至于到底一个像素对应多少逻辑单位,与视图变换和模型变换的结果都有关系,还与视口的剪裁有关。尤其在透视模型中,由于近大远小的关系,你很难说清楚到底一个像素对应多少逻辑单位。一般情况下,你可以认为窗口中看到的长度是连续的。
要在屏幕上一个有限区域内观察一些物体,需要经过四次变换。请参阅电力版红宝书第83页的图,很形象。下面我一一解释这四个步骤(仅以透视投影为例)。
首先阐明一些不言自明的默认设置:在OpenGL中,我们统一规定:人的视点永远在原点,视线方向永远指向Z轴负方向,Y轴永远向上,X轴永远向右。换言之,在OpenGL的场景中,照相机的位置和朝向是固定不变的,我们永远只能通过移动物体来取得需要的视觉效果。
以上的规定就是视图变换的内容,或者说,视图变换其实是不需要进行的。但有时为了特殊的需要,我们又必须移动视点。这时实际是把物体向相反的方向移动得到的结果。比如视点向Z轴负方向移动5个单位,与物体(不管看得到看不到)向Z轴正方向移动5个单位是等价的。因此我们往往用模型变换来代替视图变换。这个过程很复杂,而且牵扯到变换的顺序问题。有一个函数gluLookAt就是为方便我们而设的。表面看,这个函数似乎把视点移动到了(ex,ey,ez)并把视线方向指向(cx,cy,cz),实际上,这个函数是计算了反方向移动物体的变换矩阵,以后绘制的每一个物体都要乘以这个矩阵,实际等于是把物体向相反的方向移动或旋转了。所以其实视点和视线方向并没有变,只是通过函数封装了复杂的反向移动模型变换而已。
经过了视图变换和模型变换之后我们要进行投影变换。投影变换相当于照相机的取景。经过把实际坐标乘一个投影矩阵之后,原先实际的坐标值将被归一化。如果是平行投影,没什么好说的。但对于透视投影,实际是用一个平截台体(四棱台)截取整个场景,把这个平截台体内所有的坐标都变换成下面的三元组{z=(f1~f2),x=+_Z,y=+_z};f1<f2且0.0<=f1,f2<=1.0。当然,这是最简单的一种视锥,实际使用的要比这个复杂。但是也可以看出,通过这个变换,z坐标变换到了(0.0,
1.0)区间,同时分隔也变成不均匀的了。这就是glFrustum的基本原理。gluPerspective和glFrustum是一样的,只是简化了glFrustum的一些参数而已。
最后才进行视区变换,就是把这个平截台体的四壁平行透射到垂直屏幕的四个侧面上去,把截台体内部的所有物体都投射到屏幕上。
对视图变换而言,的确是改变了原先的坐标值,但是这种改变是很复杂,不好掌握的。因此为精确定位物体,我们只需考虑模型变换的坐标,假象一个摆放物体的空间,你的眼睛就在视点的位置上。
写了好多,可我觉得不画图还是很难说清楚这个过程。这是计算机图形学的基本方法,还是参考计算机图形学的教材比较好一点。另外红宝书上也有很清楚的解释,可以参考。
...全文
175 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
_铭子_ 2002-08-01
  • 打赏
  • 举报
回复
zhangyan_qd ,你好,我还有个问题问你,
如果我这样设置:
glViewport(100,100,1000,1000);
这样以来,opengl的坐标原点就在屏幕的(100,100)了,你看对不对,
谢谢!
_铭子_ 2002-08-01
  • 打赏
  • 举报
回复
谢谢,你的讲解!
我再买本书看一下!

8,303

社区成员

发帖
与我相关
我的任务
社区描述
游戏开发相关内容讨论专区
社区管理员
  • 游戏开发
  • 呆呆敲代码的小Y
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧