OpenGL - 选择性世界渲染

6
我正在建造一个迷你城市,包括城市的基本元素(道路、建筑、树等),可以在其中移动。我知道在每个帧中渲染整个模型集是不可行的...
那么,有人能给我提供一些关于如何选择性地渲染系统中仅可见部分的标准(但最简单)程序的见解吗?我的意思是,只显示可见的内容(相对于摄像机位置),而不渲染未看到的部分... 我正在使用VC++和GLUT API。

有很多方法可以做到这一点。其中之一是视锥体剔除(只绘制在视口中的内容),遮挡剔除(只绘制未完全遮挡的物体)。还有部分渲染技术,当你达到此帧的阈值时间时开始绘制,然后停止绘制。 - ChrisF
谢谢@christian。我会查看这些的。OpenGl是否提供预定义函数来帮助这些方法中的任何一个?还是我们应该从头开始实现算法? - itsraining
自从我活跃于3D图形方面已经有一段时间了,所以我并不完全了解最新情况,但是大体上由你来决定什么内容需要传送到流水线中。 - ChrisF
1
@itsraining 这种高级场景管理工具不在OpenGL的范畴之内。但实际上,OpenGL在顶点处理阶段后执行截锥体裁剪(也称为视体积裁剪)。这就是为什么只有顶点阶段(T&L或顶点着色器)从截锥体裁剪中获益,而光栅化和片段阶段(纹理或片段着色器)则没有。但当然,CPU端也可以从更少的绘制调用中受益。而且OpenGL还支持遮挡查询,虽然比较低级,但可以用来实现遮挡剔除技术。 - Christian Rau
2个回答

5
也许这篇维基百科文章可以为剔除技术领域提供一个非常基本的介绍。
一个很好的起点和最简单的技术之一是视锥体剔除。使用此方法,您可以检查场景中的每个对象是否在视图体积(视锥体)内。这基本上相当于检查几何体的某些简化边界体(如完全包含几何体的盒子或球体)是否位于由六个平面定义的视锥体内。
通过按其位置对对象进行分组并创建所谓的边界体层次结构,可以进一步优化此过程,例如,首先使用包含整个街区的边界体来检查整个城市街区是否在视图体积内,只有在街区内时才会进一步检查各个房屋。
一种更复杂的技术是遮挡剔除,这意味着检查一个物体是否完全隐藏在另一个物体后面。由于这些技术可以变得更加复杂,如果使用应该在视锥剔除之后进行。OpenGL有硬件遮挡查询可帮助您确定对象是否实际可见,但它们需要额外的工作才能正常工作。特别是对于城市,可能会有特殊的二维遮挡剔除技术(很久以前我听说过,不确定现在是否仍然适用)。
这只是一个非常广泛的概述,可以自行搜索单个关键字。仔细衡量额外的CPU开销是否值得(尤其是对于复杂的遮挡剔除技术),考虑到现在的趋势是将尽可能多的几何图形批处理到单个绘制调用中(顺便说一下,希望您不要使用即时模式glBegin/glEnd,否则将其更改为顶点数组或更好的VBO是您议程上的第一项)。但视锥剔除可能是一个不错且易于入手的起点,特别是如果城市规模较大。

0

搜索“二叉空间分割树”。

BSP树是确定从相机视角和位置应该呈现什么的好方法。老派的第一人称射击游戏,例如Quake等,使用它们(或至少使用了该原理的某种派生形式)。

这里有一个很好的FAQ

其他好的资源: 链接 链接


现在的“尽可能将多个物体批量绘制到单个调用中”的优化图形硬件上,传统的分割多边形的BSP树已经完全行不通了。而且,文件扩展名“.bsp”并不意味着它与BSP树有任何关系(或许从最远的意义上说有一点点)。如果你想要的话,这些文件应该以“.pvs”结尾。 - Christian Rau
谢谢大家的帮助和提供链接。我想现在我会选择视锥体剔除,如果我能处理好这些东西,可能还会使用遮挡剔除。 :) - itsraining

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接