为什么添加颜色附件导致3倍减速?

时间:2016-07-21 12:20:49

标签: c++ opengl framebuffer fbo

我正在深度渲染一些模型,如下所示:

m_fbo = new globjects::Framebuffer();
depthBuffer = globjects::Texture::createDefault();
depthBuffer->storage2D(1, GL_DEPTH_COMPONENT32F, size, size);
m_fbo->attachTexture(GL_DEPTH_ATTACHMENT, depthBuffer);

m_fbo->bind();
... draw all the things

现在,当我像这样添加颜色附件时:

m_fbo = new globjects::Framebuffer();
depthBuffer = globjects::Texture::createDefault();
depthBuffer->storage2D(1, GL_DEPTH_COMPONENT32F, size, size);
m_fbo->attachTexture(GL_DEPTH_ATTACHMENT, depthBuffer);

attributeBuffer = globjects::Texture::createDefault();
attributeBuffer->storage2D(1, <format>, size, size);
m_fbo->attachTexture(GL_COLOR_ATTACHMENT0, attributeBuffer);

m_fbo->bind();
... draw all the things

取决于属性缓冲区的格式,渲染时间从2.6ms到5ms(R8,RG8),8.5ms(RGB8,RGBA8,R32F)或14.5ms(RG32F,RGBA32F)(用opengl定时器查询测量)

我甚至没有更改片段着色器,因此我不计算任何其他值来写入该颜色缓冲区。如果我注释掉attachTexture行,则渲染时间会再次下降。

手头的纹理是2Kx2K阴影贴图。我使用的程序细分模型,将每个三角形转换为一个点,并将该点与gl_PointSize = 1一起渲染到该图集中的一个随机选择的64x64图块中。 tesselation和几何着色器很重,所以我不认为这是带宽或填充限制。如果我渲染成一个大的阴影贴图而不是多个小阴影贴图,这个放慢速度要小得多(1.9到2.1毫秒)。

如果我在几何着色器中手动将属性写入带有imageStore的纹理并且不使用颜色附件,那么减速也是合理的(1.9到2.3ms)

此外,当我开始使用nsight进行跟踪时,这种减速会神秘地消失,这使得无法对此进行分析。

为什么会发生这种情况的任何想法?

我使用750 Ti。

1 个答案:

答案 0 :(得分:1)

与大多数OpenGL性能问题一样,它们依赖于实现。因此我们只能猜测,除非我们知道实际的实现是如何工作的。

  1. GPU通常针对仅深度渲染进行优化。由于您要添加颜色附件,因此不再进行仅深度渲染。
  2. 您的颜色附件格式为GL_R32F。与常规的旧GL_RGBA8格式相比,此格式渲染速度更快。
  3. 如果每次切换到随机选择的64x64阴影贴图时更改渲染目标,这都非常慢。更改渲染目标是一项非常昂贵的操作,但有一些方法可以解决它。请参阅此演示文稿的第29页:http://http.download.nvidia.com/developer/presentations/2005/GDC/OpenGL_Day/OpenGL_FrameBuffer_Object.pdf
  4. 如果我理解正确的话,你会渲染很多1个像素的三角形。这很慢。这是因为GPU在2x2像素的组中栅格化像素。即使只渲染了一个像素,硬件仍会运行着色器4次,然后只丢弃3个像素。如果您渲染的只是1像素三角形,那么您实际上会浪费3/4的光栅化性能。
  5. 请问您为何使用深度附件格式GL_DEPTH_COMPONENT32F?大多数GPU甚至不支持32位深度缓冲区。通常为24位。您是否尝试使用GL_DEPTH_COMPONENT24GL_DEPTH_COMPONENT32

    但这是一个非常特殊的问题。您是否尝试更新GPU驱动程序?