现在的位置: 首页 > 综合 > 正文

OpenGL 视景体

2014年09月02日 ⁄ 综合 ⁄ 共 1671字 ⁄ 字号 评论关闭

视景体裁剪

gluPerspectivegluLookAt函数

1.    视景体就是包括一些模型在屏幕中的显示,这个视景体就是通过使用透视投影等摄像机的参数来设置的。

这个看起来像金字塔,塔尖就是摄像机,塔地是远平面,中间是近平面,故名叫做锥台。

所有在屏幕里面的模型都会显示,甚至是部分在屏幕里面的,所以那些在锥台外面就不需要去绘制,因为它们根本就看不见。

如上图,所有绿色(都在锥台里面)和所有黄色(在锥台里面的部分)都会被绘制,而红色的模型都不会被绘制,注意绿色的那个球体是看不见的,但是因为它在视景体里面,所以在任何情况下都会被绘制。

视景体裁剪的目标是判断哪些模型在视景体里面(全部or部分),裁剪掉那些不在视景体里面的任何模型。只要模型在视景体里面,甚至是部分在里面,它都会被发送到图形硬件。最后,所有被发送到图形硬件那些可见的被保存到顶点数据中。

2.    视景体形状

让我们先回顾一下这两个函数:

·        gluPerspective(fov, ratio, nearDist, farDist);

·        gluLookAt(px,py,pz, lx,ly,lz, ux,uy,uz);

塔尖是摄像机的位置(px, py, pz),视图射线方向是d = l – p,这边的l是(lx, ly, lz),而p是(px, py, pz),而近平面和远平面式垂直于视图射线,它们的距离分别是nearDist和farDist,而视景体就是由这些平面组成的。

近平面的高度和宽度的计算公式如下:

而远平面的计算公式如下:

为了计算视景体裁剪面必须知道以下两个方面:

(1)求出视景体的信息,这些信息可能无时无刻在变换中,比如相机移动或者投影矩阵变换等。

(2)测试模型是否在视景体中。

3.    提取视景体----几何方法

使用几何就是通过视景体的六个平面进行计算的。

平面是通过向法向朝向视景体,测试每一个模型是否在视景体中。

在这一节中,首先我们要先计算出六个平面,判断就先放到下一节中。

第一步要先算出视景体的六个顶点坐标,然后利用这些坐标定义六个平面。

下面这幅图表示这些顶点坐标:

让我们重新定义以下变量:

p-相机位置;

d-相机的朝向,在这边要单元化;

nearDist-相机跟近平面的距离;

Hnear-近平面的高度;

Wnear-近平面的宽度;

farDist-相机跟远平面的距离;

Hfar-远平面的高度;

Wfar-远平面的宽度;

还有一些如up(向上向量)和right(向右向量);

下面这个图就是表示如何计算远平面的左上的顶点坐标ftl的:

计算公式如下:

三个顶点组成可以定义一个平面,因此为了定义远平面可以用ftl,ftr,fbr组成。

关于本方面的具体编码内容,可以参考工程。

4.    提取视景体方法---裁剪空间法

这里介绍另外一种方法,它是裁剪空间的。

假设在3D世界中一个点p=(x,y,z,1),也假设一个模型变换矩阵M和一个投影矩阵P,这个点p经过矩阵M和P变换之后的裁剪空间坐标点pc=(xc, yc, zc, wc):

pc齐次坐标pcn:

在单一化的裁剪空间中,视景体的中心位于原点处,被以下包围盒:

·        Left Plane: x’ = -1

·        Right Plane: x’ = 1

·        Top Plane: y’ = 1

·        Bottom Plane: y’ = -1

·        Near Plane: z’ = -1

·        Far Plane: z’ = 1

这就意味着,如果要使点pcn在视景体中,那么要满足以下:

然后在非单一化的顶点pc要在视景体中,要满足以下:

点pc在左平面的右边,如果满足以下:

考虑p和A=MP可以用以下来描述:

xc和wc可以通过p和A来定义:

因此如果点p在左平面右边那么不定式成立:

一个代数不等式如下:

所以左平面方式Ax+By+Cz+D=0可以用如下定义:

Col1和col4是矩阵A的第一、四列元素。

右平面也可以用同样的方式:

右平面的系数由以下计算:

其余平面如下:

底平面:

顶平面:

近平面:

远平面:

裁剪空间具体细节参考代码

 

抱歉!评论已关闭.