镶嵌如何提高性能?

时间:2014-07-17 01:54:15

标签: opengl graphics directx glsl tessellation

似乎反直觉的是,计算更多顶点而不是仅仅从vram中读取更多顶点会更快。但是,如果内存带宽是使得镶嵌值得的问题,那么为什么存在像置换贴图这样的东西呢?在曲面细分着色器中,如果从纹理中读取,则无论如何都要访问vram。纹理看起来比原始顶点更便宜吗?为什么曲面细分快?

假设您使用非常低的多边形模型进行了32的顶点放大。这会比仅使用8或者等级的曲面细分顶点放大的更高的多边形模型更快。或者换句话说,你是否通过镶嵌得越多线性地获得性能?

4 个答案:

答案 0 :(得分:6)

没有任何一点能够在每个可能的实例中提供更好的曲面细分。每个用例都有不同的好处和权衡。有些事情可能有助于使曲面细分比替代品更快:

  • 内存带宽:现代计算机在很大程度上受内存速度的限制。即使您使用纹理,单个读取也可能低至4个字节,而不是存储顶点数据通常所需的32个字节。
  • 细节级别(LOD):使用曲面细分着色器,您可以避免区域过于详细,同时仍然确保场景的其余部分具有足够的细节。
  • 更少的Verticies:意味着更少的顶点着色器和管道的每个阶段的执行。
  • 减少CPU开销:可能需要较少的绘制调用,尤其是在您不再需要在CPU上执行LOD时。

我可能错过了其他一些因素......

答案 1 :(得分:3)

总是在处理器和内存之间进行权衡。细分是一种可以节省内存和带宽但以GPU性能为代价的方法。

为什么要使用细分: 使用置换贴图进行细分可显着降低场景中动画或多实例对象的内存带宽。但它对静态单个对象不是很有用。

假设您有一个在屏幕上运行的精灵。如果精灵是一个高细节(100万个顶点),那么每次动画例程移动/变形网格时,所有100万个顶点都会被转换并重新加载到每帧的GPU。

但是,如果使用具有镶嵌和位移的低细节模型(50-100k顶点)。然后将置换贴图存储在gpu上一次。你为动画更新50k网格并重新加载每帧少得多的网格,然后GPU使用已经加载的置换贴图细分多达4-5百万个网格。

最终结果是你获得2-4倍的网格细节,内存带宽为1/20。现在假设你一次在屏幕上有20-30个这些精灵。

为什么不应该使用镶嵌细分:要动态添加此细节,gpu必须消耗处理能力,以便在开始运行所有其他顶点之前计算每个细分顶点的3d位置着色器。

您需要注意的主要区别是,这只会在您实例化和/或设置几何体动画时帮助您。

如果你有一个永远不会移动的高细节静态网格物体,并且屏幕上只有一个实例,那么以完整的细节上传几何体会更快。曲面细分只会增加复杂性并消耗管道中的周期。

需要权衡: 通过对静态网格物体使用曲面细分,可以获得轻微的内存带宽。因为顶点需要浮点的3个坐标才能被gpu理解。但是采样位移图使用1个固定点数据坐标是有用的。因为置换贴图针对相邻顶点进行归一化。因此它可以即时计算额外数据。但是,对于每个细分顶点,每帧执行该计算。这会占用着色器时间,如果使用静态网格物体则不需要。

但是,如果为了LOD目的而关闭或关闭曲面细分,与高细节静态网格相比,它可以为不需要细节的对象节省着色器时间。

因此,细分对于改进动态/实例化网格的细节总是一个好主意。

但是对于静态网格或单一网格,它在LOD能力和管道复杂性之间进行权衡。远处的高细节网格燃烧更多的计算时间,然后关闭曲面细分的细分网格。但是前景中的高细节网格比带有细分的细分网格占用更少的计算时间。

然而,要考虑的一件大事是,随着物体越来越近,慢慢地将曲面细分调高,看起来比立即用高细节网格替换低细节网格更好。因此,当平滑LOD是一个很大的问题时,那么肯定会使用曲面细分。 ...或使用曲面细分到某个点,然后用高细节网格替换它。但是,如果您不担心内存不足并且始终将这两个版本保留在gpu上,那么这只是一个好主意。否则你将再次燃烧带宽。

同样,总是在内存使用和处理器使用之间进行权衡。

答案 2 :(得分:1)

曲面细分的一点是,您可以使用更多有用的顶点(靠近相机),使用较少的顶点(距离相机较远)。因此,您可以获得更详细的几何体效果,而无需在场景中的任何位置使用它。

答案 3 :(得分:1)

(在OpenGL的上下文中) 正如其他人已经说过的那样,曲面细分的使用可以被认为是增加的gpu计算时间与应用程序和OpenGL之间的带宽减少之间的交易。

当你考虑它时,哪个有意义?如果你没有发送所有顶点,必须有一些方法可以获得它们的位置。

大多数现代应用程序以某种方式定义模型(顶点等的集合等),然后将其发送到gpu。有一段时间,从而否定了大多数用例,在这些用例中你更希望Tessellation增加“性能”(性能是更高的帧率/更低的执行时间,我假设)只要你有足够的可用内存留在GPU上此

在动画的情况下,您不必发送模型的修改顶点来替换gpu-memory中已有的信息。大多数现代应用程序使用骨骼集合,甚至可以存在于gpu上的权重。你发送一个像时间一样的统一变量,这就是应用程序需要做的全部。其余的工作在GPU上完成。

在进入主显示/渲染循环之前,甚至可以将静态预定义的一组LOD网格上传到GPU。权衡的是,您将无法控制细节的粒度,甚至几乎与镶嵌细分的细节一样。

因此,如果我们可以修改gpu上的数据而不从应用程序发送比我们使用镶嵌细分更多的数据,那么为什么或何时我们想要使用曲面细分?

  1. 正如其他人已经说过的那样,对LOD的绝对控制是一个很好的理由。
  2. 动态内容生成。让gpu ADD顶点就位,而不是发送你在CPU上生成的整个新网格,甚至是应用程序中网格的新“位”,效率更高(帧/执行时间更快)。 / LI>
  3. 当你已经在gpu上填满了每个内存时,你根本无法在缓冲区中存储任何其他东西。
  4. 总结中的一个简单结论。 曲面细分如何提高性能?

    在开始渲染之前,无法定义顶点数据并将其从应用程序上传到gpu。这是镶嵌是唯一正确的决定。通常情况下,这是不正确的。