我的场景和Tris小于1,000,000次需要多次将同一场景渲染为不同的微小纹理(我们称它们为“反弹”)。
我以一种幼稚的方式开始实现,所以我很快遇到了一些性能问题:
使用我的1TFlops笔记本电脑GPU,我可以渲染我的1M多边形场景,在降低30FPS波纹管之前可以有200次“反弹”。
我的“朴素”算法看起来像这样伪代码:
for (unsigned int i = 0; i < res ; ++i) {
UpdateCameraUniform(i);
glBindFramebuffer(GL_FRAMEBUFFER, BounceFbo[i]);
glDrawBuffers(1, renderBuffer[i]);
for (Mesh& m : Scene) {
m.render();
}
}
与
Mesh::render() {
UpdateTransformUniform();
glBindVertexArray(_vao);
glBindBuffer(GL_ARRAY_BUFFER, _vbo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
glDrawElements(GL_TRIANGLES, size, GL_UNSIGNED_INT, 0);
}
完整代码在这里(该仓库真的很乱现在...)。
我需要找到一种渲染场景的新策略,所以我搜索了可以做什么。
我想我有2种策略:
尝试减少m的数量(或性能) y通话。似乎有一些魔术函数,例如glMultiDraw *(我在“ OpenGL超级”的文章中找到了它)。但是我真的不明白这是做什么的:
此渲染是否多次渲染相同的网格?
不同的网格但只有一个着色器?
不同的网格与
试图减少渲染时间,同时使用与之相同的技术在“ Bounces”中多次渲染相同的网格,但是我却完全不知道它是如何工作的,甚至可以应用于我...
显然我愿意接受任何其他建议。
编辑:我可以达到200次“反弹”,而不是35次
#1 楼
您应该始终进行剖析以确定减速发生的位置。从您的问题来看,目前尚不清楚您的工作是受CPU限制还是受GPU限制。但是我真的不明白这是什么:这是否多次渲染同一网格?不同的网格,但只有一个着色器?不同的网格物体使用不同的着色器,但CPU开销较低?
glMultiDraw*
绘制命令用于允许您在一个绘制调用中呈现多个对象。在OpenGL 3.0及更高版本中,这意味着您可以指定一个VBO来容纳一堆对象并使用glMultiDraw*
渲染它们。您将使用同一着色器。如果要多次渲染同一对象,则使用实例化等方法将是一个很好的解决方案。这一切都涉及绘制调用。如果只有少数几个网格具有一百万个三角形,则渲染将不会看到巨大的加速。您没有指定帧缓冲区的大小,但是如果帧缓冲区的大小足够小,则可能会导致许多小三角形的严重透支。如果图像真的那么小,也许您应该考虑添加LOD系统或使用较低的多边形网格和细分。
尝试减少渲染时间,同时渲染同一网格的多个时间在“弹跳”中使用与本技术相同的技术
立体声实例渲染是一种专门用于VR的技术。它基于这样的假设,即每只眼睛的场景几乎相同,因此它使用实例化一次渲染到屏幕的两侧。但是,如果弹跳渲染的几何形状相似,则只要弹跳是独立的,便可以将多个弹跳渲染到更大的帧缓冲区上。避免帧缓冲区切换(这是一个相当昂贵的过程)可能会提高速度。
在较新的OpenGL版本(4.0及更高版本)中,添加了对间接渲染的支持,该支持使您可以通过GPU计算来确定参数,但尚不清楚在这种情况下是否对您有帮助。
评论
$ \ begingroup $
当我达到20FPS时,我的CPU负载很少会超过30%,因此我受GPU约束。对于我现在的glMultiDraw *问题,我使用矩阵移动对象(UpdateTransformUniform()调用),是否可以将glMultiDrawElements链接到统一缓冲区或类似缓冲区?对于我的缓冲区,我的最终缓冲区是4 1920x1080(我正在使用延迟渲染),而跳动是4 64x64(很快将替换为1 64x64)。对于算法:我应该使用实例渲染在每个网格中循环弹跳,还是为每个反弹循环glMultiDraw我的网格。
$ \ endgroup $
–新闻
16-11-20在18:36
$ \ begingroup $
实际上,如果使用统一转换矩阵,则我想这就是您想要的:glDrawElementsInstancedBaseVertexBaseInstance(OpenGL 4.2)。这里是关于它的更多信息:gamedev.net/topic/…
$ \ endgroup $
–aces
16年11月21日在5:31
$ \ begingroup $
我问一个与您在这里问过类似的问题:computergraphics.stackexchange.com/questions/4241/…
$ \ endgroup $
–aces
16年11月21日在5:41
$ \ begingroup $
无论哪种方式,如果您的性能受到GPU的限制,都不会有太大的不同。对于64x64的网格,您将进行大量重绘,即使对于延迟的渲染器也是如此,因此您应该在此处进行优化。但是关于您的后续问题,我将浏览链接的幻灯片,看看是否可以帮助您解决这种情况(将其扩展到网格而不是两个屏幕)。
$ \ endgroup $
–aces
16年11月21日在5:42
$ \ begingroup $
好吧,我几乎是个好主意,最后一个问题:立体实例渲染似乎使用1个渲染目标,但分割成2个,但是我有多个FBO。我找不到跨多个FBO使用实例的方法,这是可能的吗?
$ \ endgroup $
–新闻
16-11-25在20:09
评论
@trichoplax是的,但是我的声誉不够高,无法放置2个以上的链接,因此我更改了它,然后忘了更改我的句子对不起= /我会解决的我(终于)修复了