OpenGL - 选择性世界渲染

Posted

技术标签:

【中文标题】OpenGL - 选择性世界渲染【英文标题】:OpenGL - selective world rendering 【发布时间】:2011-11-02 17:06:26 【问题描述】:

我正在建造一个具有城市基本外观(道路、建筑物、树木等)的微型城市,您可以在其中四处走动。我知道在每一帧中渲染整个模型集是行不通的……

那么任何人都可以让我了解用于选择性地仅渲染系统的可见部分的标准(但最简单的)过程吗?我的意思是,只显示可见的东西(相对于相机位置)而不渲染看不见的部分.. 我正在使用 VC++ 和 GLUT API。

【问题讨论】:

有很多方法可以做到这一点。截锥体剔除(仅绘制视口中的内容),遮挡剔除(仅绘制未完全模糊的东西)仅举两个。还有部分渲染技术是您开始绘制然后在达到此帧的阈值时间时停止。 谢谢@christian.. 我会去看看那些.. OpenGl 是否提供预定义的函数来帮助这些方法?还是我们应该从头开始实现算法? 自从我开始从事 3D 图形业务以来已经有一段时间了,所以我并不完全了解最新情况,但很大程度上取决于您决定将哪些内容发送到管道中。 @itsraining 这种高级场景管理工具不在 OpenGL 的范围内。但实际上 OpenGL 在顶点处理阶段之后执行平截头体剔除(在那里称为视图体积裁剪)。这就是为什么只有顶点阶段(T&L,或顶点着色器)从截锥体剔除中受益,而光栅化和片段阶段(纹理或片段着色器)都没有。但当然,CPU 方面的利润也来自较少的绘制调用。而且OpenGL还支持遮挡查询,这是相当低级的,但可以用来实现遮挡剔除技术。 【参考方案1】:

也许this Wikipedia article 提供了关于剔除技术领域的非常基本的介绍。

一个很好的起点和最简单的技术之一是视锥体剔除。使用此方法,您可以检查场景中的每个对象是否在查看体积内(查看平截头体)。这基本上相当于检查几何体(如完全包含几何体的盒子或球体)的一些简化边界体积,如果它位于由六个平面定义的视锥体内。

这可以通过按位置对对象进行分组并创建所谓的包围体层次结构来进一步优化,例如首先检查整个城市街区是否在查看体积内(通过使用包含整个街区的边界体积),如果是,则进一步检查各个房屋。

更复杂的技术是遮挡剔除,这意味着检查一个对象是否完全隐藏在另一个对象后面。因为这些技术可能会变得更加复杂,所以它应该(如果完成的话)实际上应该在视锥体剔除之后完成。 OpenGL 具有硬件遮挡查询,可以帮助您确定对象是否实际可见,但它们需要一些额外的工作才能正常工作。尤其是城市,可能有特殊的二维遮挡剔除技术(很久以前听说过,不知道)。

这只是一个非常广泛的概述,请随意在谷歌上搜索各个关键字。考虑到现在的趋势是将尽可能多的几何图形批处理到单个绘图调用中(顺便说一句,我希望您不要使用即时模式glBegin/glEnd,否则将其更改为顶点数组或更好的 VBO 是您议程上的第一点)。但是视锥体剔除可能是一个不错且简单的起点,尤其是在城市变得相当大的情况下。

【讨论】:

【参考方案2】:

谷歌“二进制空间分区树”。

BSP 树是确定应该从相机的视角和位置渲染什么的好方法。老式的第一人称射击游戏,即 Quake et al,使用了它们(或至少是该原理的一些推导)。

这是一个很好的FAQ。

其他好资源: link link

【讨论】:

对多边形进行分区的经典 BSP 树在当今“尝试尽可能多地批处理到单个绘图调用”优化的图形硬件上是完全不可行的。并且不要让以“.bsp”结尾的文件欺骗你它与 BSP 树有任何关系(也许在最远的意义上)。如果您愿意,这些文件应该以“.pvs”结尾。 感谢你们的帮助和提供链接..我想我现在会使用平截头体剔除..如果我能处理这些东西,也许可以使用遮挡剔除..:)

以上是关于OpenGL - 选择性世界渲染的主要内容,如果未能解决你的问题,请参考以下文章

OpenGL中的拾取模式( Picking)

有没有办法在多 GPU 环境中以编程方式选择渲染 GPU? (视窗)

哪些 CSS 选择器或规则可以显着影响现实世界中的前端布局/渲染性能?

如何为 OpenGL 文本渲染计算字符映射中的最佳字形边界

OpenGL学习之路——窗口

opengl 3 qt渲染空白屏幕