正如我所知,批处理和实例化用于减少静态网格的绘制调用量。但是动态网格呢?如何优化他们的抽奖次数?实例化和批处理这会产生很大的开销,因为每帧都需要用cpu重新计算位置。还是最好使用单独的绘制调用来绘制动态网格?
需要记住以下几个性能注意事项:
- 每个
glDraw..()
都有一些开销,所以您希望将这些开销最小化。这就是实例化带来性能优势的原因之一。(更好的缓存行为是另一回事。( - 主机到设备的数据传输(
glBufferData()
(甚至比draw调用还要慢。因此,我们尝试将数据保留在GPU上(顶点缓冲区、索引缓冲区、纹理(,而不是在每帧传输数据
在您的情况下,有几种方法可以获得高性能的动态网格。
-
伪造它。你真的需要动态网格吗?特别是,你必须生成新的网格数据吗?或者,您可以通过着色器中的变换来实现同样的效果吗?
-
在GPU上生成网格。这可以在计算着色器(为了获得最佳性能(或几何体和/或镶嵌着色器中完成。这有其自身的开销,但由于GPU上发生的一切,您不会遇到更昂贵的
glDraw...()
或主机GPU副本。
- 请注意,几何体着色器相对较慢,但它们仍然比将新的顶点+索引缓冲区从CPU复制到GPU更快*
-
如果您的";动态的";网格有有限数量的状态,只需将它们全部保留在GPU上,并根据需要在它们之间切换即可。
-
如果这是另一个API,如Vulkan,则可以在单独的线程中生成网格,并将其传输到GPU,同时绘制其他内容。这是一个非常复杂的主题,就像所有与显式图形API相关的内容一样。