10

计算更多的顶点而不是仅仅从 vram 读取更多会更快,这似乎违反直觉。但是,如果内存带宽是使曲面细分值得的问题,那么为什么会存在诸如置换贴图之类的东西呢?在曲面细分着色器中,如果您从纹理中读取数据,那么无论如何您访问 vram 的次数更多。纹理查找是否比更多原始顶点便宜?为什么镶嵌速度很快?

假设你有一个 32 的顶点放大和一个非常低的多边形模型。这会比说只有镶嵌顶点放大为 8 或其他东西的更高多边形模型更快。或者换句话说,你是否会随着镶嵌的越多线性地获得性能?

4

4 回答 4

8

没有任何一个点可以在每个可能的实例中为曲面细分提供更好的性能。不同的好处和权衡适用于每个用例。一些可能有助于使镶嵌比其他方法更快的事情:

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

可能还有其他我错过的因素...

于 2014-07-17T17:05:14.650 回答
5

处理器和内存之间总是需要权衡取舍。Tessellation 是一种可以节省内存和带宽的方法,但会以 GPU 性能为代价。

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

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

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

最终结果是您可以获得 2-4 倍的网格细节和 1/20 的内存带宽。现在想象一下,您一次在屏幕上有 20-30 个这样的精灵。

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

您需要注意的主要区别是,这仅在您实例化和/或动画几何体时对您有所帮助。

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

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

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

因此,镶嵌始终是改善动态/实例化网格细节的好主意。

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

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

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

于 2015-05-18T21:11:10.883 回答
1

镶嵌的要点是在有用的地方(靠近相机)使用更多的顶点,在不太有用的地方(远离相机)使用更少的顶点。因此,您可以获得更详细的几何图形效果,而无需在场景中的任何地方使用它。

于 2014-07-17T03:15:16.883 回答
1

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

当您正确考虑时,这有意义吗?如果您没有发送所有顶点,则必须有一些方法可以获取它们的位置。

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

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

在进入主显示/渲染循环之前,甚至可以将一组静态预定义的 LOD 网格上传到 GPU。权衡是您将无法控制细节的粒度,甚至无法像使用曲面细分那样接近。

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

  1. 正如其他人已经说过的,对 LOD 的绝对控制是一个很好的理由。
  2. 动态内容生成。让 gpu ADD 顶点就位比发送您在 CPU 上生成的全新网格甚至来自应用程序的网格的新“位”要高效得多(帧/执行时间更快)。
  3. 当您已经填满了 gpu 上的所有内存并且您根本无法在缓冲区中存储任何其他内容时。

一个简单的总结。细分如何提高性能?

在开始渲染之前无法定义顶点数据并将其从应用程序上传到 gpu 时。那是唯一一次镶嵌是正确的决定。很多时候,这是不真实的。

于 2017-07-13T18:39:08.510 回答