【发布时间】:2014-01-14 18:49:55
【问题描述】:
所以最近我一直在我的笔记本电脑上编写一个 fps 游戏,但是当我尝试在我的固定计算机上运行游戏时,它应该表现得更好,它运行得更慢?
这里有几个屏幕截图,比较了有和没有天空盒的简单测试场景。 (固定电脑 - 顶部,笔记本电脑 - 底部)
到目前为止,您可以看到这是我所期望的,但是当我添加相同的天空盒渲染代码 + 着色器代码时(固定计算机 - 顶部,笔记本电脑 - 底部)
正如您现在所看到的,结果完全相反,我不知道为什么如果我在固定计算机上使用天空盒向上或向后看,我会得到大约 5 的 fps。
这是天空盒的着色器代码:
#version 120
varying vec3 pl;
uniform mat4 gWM;
void main()
{
pl = vec3(gl_Vertex);
gl_Position = (gWM * gl_Vertex).xyww; // I have also tried with gl_ModelViewProjectionMatrix instead of gWM.
}
片段着色器:
#version 120
varying vec3 pl;
uniform samplerCube cubeMap;
void main()
{
gl_FragData[1] = textureCube(cubeMap, -pl);
}
实际渲染的网格是一个球体。
另一件事是,我的笔记本电脑还可以处理剩下 100+ fps 的照明计算,但如果我将这些添加到我的固定设备中,我会得到大约 15 个。
如果我的固定装置在开始时表现更差,我不会关心为什么,但因为它并不是我真的想知道 fps 丢失的地方!
固定电脑规格:
CPU:英特尔酷睿 i5 @ 2.80GHz
内存:4,00GB 双通道
显卡:ATI Radeon HD 4800 系列
笔记本电脑规格:
CPU:英特尔酷睿 i7 @2.00GHz
内存:8,00GB 双通道
显卡:英特尔高清显卡 4000
渲染(更新) 对于渲染,我使用这样设置的 G-Buffer(来自延迟照明教程):
glGenFramebuffers(1, &m_fbo);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_fbo);
glGenTextures(ARRAY_ELEMENTS(m_textures), m_textures);
glGenRenderbuffers(1, &m_depthBuffer);
glGenTextures(1, &m_finalTexture);
for(unsigned int i = 0; i < ARRAY_ELEMENTS(m_textures); i++){
glBindTexture(GL_TEXTURE_2D, m_textures[i]);
glTexImage2D(GL_TEXTURE_2D, 0, i == 0 ? GL_RGBA32F : GL_RGB8, WindowWidth, WindowHeight, 0, GL_RGB, GL_FLOAT, NULL);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D, m_textures[i], 0);
}
glBindRenderbuffer(GL_RENDERBUFFER, m_depthBuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_EXT, WindowWidth, WindowHeight);
glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_depthBuffer);
glBindTexture(GL_TEXTURE_2D, m_finalTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, WindowWidth, WindowHeight, 0, GL_RGB, GL_FLOAT, NULL);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT4, GL_TEXTURE_2D, m_finalTexture, 0);
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if(status != GL_FRAMEBUFFER_COMPLETE){
printf("[Error ] Framebuffer status: 0x%x\n", status);
return false;
}
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
mWidth = WindowWidth;
mHeight = WindowHeight;
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
return true;
所以我的问题:这可能是什么原因造成的?有没有解决办法?
【问题讨论】:
-
我怀疑这是填充率问题,除此之外很难说。添加天空盒时是否停止清除颜色/深度缓冲区?很多旧资源会告诉您,这是您可以对天空盒使用的优化,但在现代 GPU(使用缓冲区压缩)上却不是。另外,你渲染天空盒的顺序是什么?为了使填充率最小化,您应该在所有其他不透明几何体之后绘制它。如果您已经采用这种方式进行绘制,则可以先尝试绘制天空盒,以过分强调任何填充率限制以跟踪瓶颈。
-
@AndonM.Coleman 我将所有内容渲染到第二个帧缓冲区中,其中包含位置/漫反射/法线/texcoord 纹理2Ds 和深度+模板纹理,然后在我的光照计算之后,我将最终图像blit 到原始图像帧缓冲区。因此,我在“几何传递”之前清除了最终图像缓冲区一次。但是我只对天空盒使用漫反射纹理,而对于地形我使用其他的。我最后一次渲染天空盒,实际上我尝试先移动它,但它的 fps 更差。
-
哦,哇。如果您关心性能优化,那么会有很多问题。您可以取消位置 G-Buffer 并从深度重建位置,并且您不希望 blit 帧缓冲区,除非您尝试进行 MSAA 解析。在大多数情况下,绘制带纹理的四边形将比
glBlitFramebuffer (...)快得多。 -
@AndonM.Coleman 我已经用我用来设置 G 缓冲区的代码更新了我的问题,希望这就是你想要的!
-
32 位浮点对于除了位置缓冲区之外的所有东西来说都是多余的。更糟糕的是,它使用 32 位 RGB 而不是 RGBA。有些 GPU 无法处理 RGB32F,需要 RGBA32F。驱动程序可能会在内部将这些纹理更改为 RGBA32F,并使
A组件无法使用。知道了这一点,您也许可以将一些额外的数据编码到每个缓冲区的A组件中,并保存 1 个完整缓冲区的数据。在担心天空盒的性能之前,您应该考虑减少渲染任何东西所需的内存带宽。
标签: c++ performance opengl glsl