延迟着色渲染器中用于几何传递的常见渲染优化技术是什么?[关闭]


16

我一直在使用OpenGL 3和C ++(以及用于窗口管理的glfw)开发游戏引擎。到目前为止,我已经取得了进步,完成了除声音实体和优化之外的大部分工作。该引擎使用延迟着色,因此由于延迟着色本身是普通GPU的累赘过程,因此我想尽可能地优化渲染过程。

当前系统由一个场景组成,其中包含一个渲染器,并且当前世界和世界将实体和照明实体分开std::vectors

因此,基本上每次场景被调用时->render(),它都会调用渲染器,将世界作为参数传递,并从世界中获取实体迭代器,将其吸引到FBO,然后通过照明实体进行第二遍。而且我认为这还不够。

即使实体不在屏幕空间中,我当前的算法也会遍历所有内容。我正在考虑一种优化当前渲染算法的方法,使其仅针对可见对象调用API函数,那么优化此类渲染器的常用技术有哪些?

Answers:


41

延迟阴影只是将“实际”阴影操作“延迟”到后期的一种技术,对于减少渲染10道需要10道光照的所需遍数(例如,减少渲染次数)可能会非常有用。我的观点是,无论您使用什么渲染技术,都有某些可能的渲染优化可以减少渲染管道需要处理的对象(顶点,法线等)的数量。

渲染优化并没有事实上的标准,而是可以互换使用或一起使用以达到某些性能特征的多种技术。使用每种技术在很大程度上取决于要渲染的场景的性质。

延迟渲染尝试解决灯光数量增加时的问题,这在正向渲染中可能会使通过数量爆炸。

这些技术不会直接优化延迟的阴影部分,但是根据您的描述,延迟的阴影部分不是您的问题。但是,您的问题是您要将整个场景提交到渲染管道。因此,您的引擎必须在场景中进行处理(例如,所有1亿个顶点),才能将结果提交给g缓冲区,而其中的1亿个顶点中的大多数都可以被剔除掉,而不是提交给预处理顶点和碎片通过。

在使用前向渲染器的情况下,N个顶点将由顶点阶段总共处理,vertex count*lights count而片段阶段总共处理fragments count*number Lights,延迟阴影有效地将其减少到vertex count顶点阶段和fragments count片段计数,然后再解决实际阴影。但是,N仍然可能处理不了太多,尤其是当其中大多数可以被轻易剔除时。

在正向渲染/多次通过的情况下,这使剔除更为有效。但是请记住,大多数引擎将使用双重渲染方法,因为仅靠延迟的阴影无法解析透明对象,因此必须使用这些优化,我不知道没有一个商用引擎无法完全解决所有问题。

视锥剔除

只有完全或部分包含在视锥体中的对象才需要提交到渲染管道。这是视锥剔除的基本概念,不幸的是检查网格是否在视锥内/视锥外可能是一项昂贵的操作,因此,引擎设计人员使用近似的边界体积,例如(AABB)轴对齐边界框或边界球,尽管这可能不如使用实际网格物体的精度高,但精度差异不值得您去检查实际网格物体。

在此处输入图片说明

即使具有边界体积,您实际上也不需要检查每个边界体积,或者您可以构造边界体积层次结构以进行更早的剔除,这很大程度上取决于场景的复杂性。

对于较小的引擎,这是一种很好且简单的技术,几乎在我使用过的每个引擎中都使用。如果您的引擎不需要渲染非常复杂的场景,则建议您使用不带层次结构的“正常”边界体积/视锥检查。

边界体积层次结构

背面剔除

这是必须的,为什么绘制无论如何都不可见的面孔?渲染API提供了打开/关闭背面剔除的接口。除非您有充分的理由不打开它,例如某些CAD应用程序在某些情况下需要绘制背面,否则这是必须做的事情。

咬合剔除

使用Z缓冲区可以解析可见性确定。但是问题在于Z缓冲区的性能并不总是很好,因为Z缓冲区只能在管道的后期阶段进行解析,所以要对被遮挡的对象进行栅格化,然后可以将其写入Z缓冲区,并且Z测试未通过之前的颜色缓冲区。

遮挡剔除通过执行一些早期测试以剔除渲染视锥中的被遮挡对象来解决此问题。遮挡剔除的一种实际实现方式是使用基于点的查询,并检查从特定点视图是否可见某些对象。这也可以用于剔除对最终图像没有帮助的灯光,这在延迟的引擎渲染器中特别有用。

在此处输入图片说明

GTA5是现实世界中这种技术的一个很好的例子,其中摩天大楼被分层地放置在城市的中心,不仅是装饰品,而且还充当遮挡物,有效地遮挡了城市的其余部分并阻止了它的出现。栅格化。

LOD

详细程度

详细程度是广泛使用的技术,其思想是在网格对场景的贡献较小的情况下使用网格的简单版本。有两种常见的实现;当不再对网格做出更大的贡献时,只需用一个简单的网格即可切换网格,网格是根据某些因素选择的,例如距离和网格所占据的像素数(屏幕上的面积)。另一个版本会动态细分网格,这在地形渲染中广泛使用。

在此处输入图片说明

如果所有这些都不起作用怎么办?

好吧,这是一个好问题。

您需要做的第一件事是使用图形探查器对应用程序进行探查,并确定瓶颈在哪里。请记住,随着所呈现内容的变化,瓶颈可能会发生变化。瓶颈也可能是CPU上运行的代码的一部分,因此您也需要进行度量。

之后,您需要对瓶颈进行一些优化,请记住,对此没有正确的答案,并且硬件和硬件之间将有所不同。

一些常见的GPU优化技巧:

  • 避免在着色器中分支。
  • 尝试不同的顶点结构,例如{VNT}在同一阵列或{V},{N},{T}不同阵列中交错。
  • 从前到后绘制场景。
  • 例如,在某些图像不需要Z测试的情况下,请在某些时候关闭Z缓冲区。
  • 使用压缩纹理。

一些常见的CPU优化技巧:

  • 将内联函数用于小功能。
  • 尽可能使用SIMD(单指令多数据)。
  • 避免缓存不友好的内存跳转。
  • 将VBO与“正确”的数据量一起使用。(取决于您的硬件),但通常更少的绘制调用会更好。

但是,如果我的瓶颈在延迟的阴影中怎么办?

在这种情况下,由于延迟着色更加关注灯光,因此最明显的部分是优化实际着色计算。请注意以下几点:

  • 渲染实际上影响最终图像的灯光。换句话说,剔除无用的灯光。使用前面提到的遮挡剔除可以有效地实现这一点。
  • 此灯是否需要镜面反射镜或其他某些组件?也许不吧。
  • 这会投下阴影吗?有些灯光不需要投射阴影。
  • 可以对这种光贡献进行预先计算吗?如果它没有移动,则可能可以对某些方面进行预先计算。

抱歉,这些与延迟着色无关,它们实际上是该技术有效缓解的确切性能问题,因此要进行的最无用的优化应将重点放在照明通行证上,因为如果照明成本不是占主导地位的时间选择器,延迟阴影可能是错误的选择。
MickLH 2013年

@MickLH不幸的是,显然您没有读过这个问题,他的问题主要是他每次都在整个场景中进行迭代,并且他没有提及有关递减阴影的任何瓶颈。首先,我提到当有很多灯光/材质时,有阴影的阴影解决了通行证爆炸问题。但是我随后补充说,无论向前或推迟阴影技术如何,对于所有引擎而言,这些都是必须进行的优化。关于这些技术消除的确切问题,我非常不同意,我不能在这里解决所有问题(
跟进

在没有例如截锥体剔除的情况下构建延迟的引擎确实很愚蠢,因此引擎将进行处理(例如1亿个顶点)只是为了将结果提交给g缓冲区。不同的阴影解决了一个不同的问题,这不是他的问题,他的问题是将所有几何图形提交给管道。
concept3d13 2011年

尽管我同意在照明计算上应该进行一些优化,但如果照明计算不是主导,那么推迟是错误的做法。但这又不是他的问题。
concept3d

如果您清楚地知道这些优化实际上对于延迟渲染器而言效果最差,我将撤回我的投票,因为这表明您没有向他/她的Google员工展示性能问题与延迟着色无关
MickLH 2013年

6

您的问题与延迟着色无关,无论如何,在尝试加速某些特定部分之前,您需要实现渲染器的基本核心元素。

完成对concept3d的解释后,如果实际上发现需要优化延迟的着色器本身(与整个栅格化过程相反),则可以实现“基于图块的延迟着色”。

如果您不受动态灯光数量的限制,则应考虑为什么要使用延期着色,但是如果您这样做,那么您将想尝试使《战地风云3》成为可能的优化。(他们在其公开PDF幻灯片10中对此进行了提示:http : //dice.se/wp-content/uploads/GDC11_DX11inBF3_Public.pdf

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.