我像这样渲染一些模型的深度:
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.6 毫秒变为 5 毫秒(R8、RG8)、8.5 毫秒(RGB8、RGBA8、R32F)或 14.5 毫秒(RG32F、RGBA32F)(使用 opengl 计时器查询测量) .
我什至没有更改片段着色器,所以我没有计算任何额外的值来写入该颜色缓冲区。如果我注释掉 attachTexture
行,渲染时间会再次下降。
手边的纹理是一个 2Kx2K 的阴影贴图集。我使用的程序镶嵌模型,将每个三角形转换为一个点,并将 gl_PointSize = 1 的点渲染到该图集内随机选择的 64x64 瓦片中。曲面 segmentation 和几何着色器非常繁重,所以我不认为这是带宽或填充率限制。如果我渲染成一个大阴影贴图而不是多个小阴影贴图,这种减速会小得多(1.9 到 2.1 毫秒)。
如果我在几何着色器中使用 imageStore 手动将属性写入纹理并且不使用颜色附件,那么减速也是合理的(1.9 到 2.3 毫秒)
此外,当我开始使用 nsight 进行跟踪时,这种减速神秘地消失了,这使得无法对此进行分析。
知道为什么会发生这种情况吗?
我使用的是 750 Ti。
最佳答案
与大多数 OpenGL 性能问题一样,它们取决于实现。因此我们只能猜测,除非我们知道实际的实现是如何工作的。
- GPU 通常针对深度渲染进行了优化。由于您正在添加颜色附件,因此您不再进行仅深度渲染。
- 您的颜色附件格式是
GL_R32F
。这种格式的渲染速度很可能比常规的旧GL_RGBA8
格式慢。 - 如果每次切换到随机选择的 64x64 阴影贴图时都更改渲染目标,这真的很慢。更改渲染目标是一项非常昂贵的操作,但有一些方法可以解决它。请参阅本演示文稿的第 29 页:http://http.download.nvidia.com/developer/presentations/2005/GDC/OpenGL_Day/OpenGL_FrameBuffer_Object.pdf
- 如果我没理解错的话,您正在渲染许多 1 像素的三角形。这很慢。这是因为 GPU 以 2x2 像素为一组对像素进行光栅化。即使只渲染一个像素,硬件仍会运行着色器 4 次,然后仅丢弃 3 个像素。如果您渲染的只是 1 个像素的三角形,那么您实际上浪费了 3/4 的光栅化性能。
请问您为什么使用深度附件格式 GL_DEPTH_COMPONENT32F
?大多数 GPU 甚至不支持 32 位深度缓冲区。通常为 24 位。您是否尝试过使用 GL_DEPTH_COMPONENT24
或 GL_DEPTH_COMPONENT32
?
虽然这是一个非常特殊的问题。您是否尝试更新您的 GPU 驱动程序?
关于c++ - 为什么添加颜色附件会导致速度降低 3 倍?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38504139/