镶嵌如何提高性能?

Tho*_*mas 8 opengl directx graphics glsl tessellation

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

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

fin*_*lia 6

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

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

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


guy*_*lla 5

处理器和内存之间总是需要权衡。曲面细分是一种可以节省内存和带宽的方法,但会牺牲 GPU 性能。

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

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

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

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

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

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

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

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

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

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

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

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

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