C++ C++;Opengl Glsl着色器性能问题

C++ C++;Opengl Glsl着色器性能问题,c++,performance,opengl,glsl,C++,Performance,Opengl,Glsl,所以最近我一直在我的笔记本电脑上编程一个fps游戏,但当我试图在我的固定电脑上运行游戏时,它应该表现得更好,但运行得更慢 下面是几个截图,比较了一个简单的测试场景,有没有skybox。(固定式计算机-顶部,笔记本电脑-底部) 正如你目前所看到的,这是我所期望的,但当我添加相同的skybox渲染代码+着色器代码(固定电脑-顶部,笔记本电脑-底部)时 正如你现在看到的,结果是完全相反的,我不知道为什么如果我在静止的电脑上用skybox向上或向后看,我会得到大约5的fps 以下是skybox的

所以最近我一直在我的笔记本电脑上编程一个fps游戏,但当我试图在我的固定电脑上运行游戏时,它应该表现得更好,但运行得更慢

下面是几个截图,比较了一个简单的测试场景,有没有skybox。(固定式计算机-顶部,笔记本电脑-底部)

正如你目前所看到的,这是我所期望的,但当我添加相同的skybox渲染代码+着色器代码(固定电脑-顶部,笔记本电脑-底部)时

正如你现在看到的,结果是完全相反的,我不知道为什么如果我在静止的电脑上用skybox向上或向后看,我会得到大约5的fps

以下是skybox的着色器代码:

#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:Intel Core i5@2.80GHz

RAM:4,00GB双通道

图形:ATI Radeon HD 4800系列

笔记本电脑规格:

CPU:Intel Core i7@2.00GHz

RAM:8000 GB双通道

图形:英特尔高清图形4000

渲染(更新) 对于渲染,我使用如下设置的G缓冲区(来自不同照明的教程):

glGenFramebuffers(1,&mufbo);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER,m_fbo);
glGenTextures(数组元素(m_纹理)、m_纹理);
glGenRenderbuffers(1,&m_depthBuffer);
GlgenTexture(1和m_finalTexture);
for(无符号整数i=0;i<数组元素(m_纹理);i++){
glBindTexture(GL_TEXTURE_2D,m_TEXTURE[i]);
GLTEXAGE2D(GL_纹理_2D,0,i==0?GL_RGBA32F:GL_RGB8,窗宽,窗高,0,GL_RGB,GL_浮点,NULL);
glTexParameterf(GL_纹理2D,GL_纹理最小过滤器,GL_最近);
glTexParameterf(GL_纹理2D,GL_纹理MAG_过滤器,GL_最近);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER,GL_COLOR_ATTACHMENT0+i,GL_TEXTURE_2D,m_textures[i],0);
}
glBindRenderbuffer(GL_RENDERBUFFER,m_depthBuffer);
GLrenderBuffer存储(GL_RENDERBUFFER、GL_DEPTH24_模具8_EXT、窗宽、窗高);
glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER、GL_DEPTH_STENCIL_ATTACHMENT、GL_RENDERBUFFER、m_depthBuffer);
glBindTexture(GL_纹理2D,m_最终纹理);
GLTEXAGE2D(GL_纹理_2D,0,GL_RGBA,窗宽,窗高,0,GL_RGB,GL_浮点,NULL);
glTexParameterf(GL_纹理2D,GL_纹理最小过滤器,GL_最近);
glTexParameterf(GL_纹理2D,GL_纹理MAG_过滤器,GL_最近);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER,GL_COLOR_ATTACHMENT4,GL_TEXTURE_2D,m_finalTexture,0);
GLenum状态=glCheckFramebufferStatus(GLU帧缓冲区);
如果(状态!=GL\U帧缓冲区\U完成){
printf(“[错误]帧缓冲区状态:0x%x\n”,状态);
返回false;
}
glClear(GL_颜色_缓冲_位| GL_深度_缓冲_位);
mWidth=窗宽;
mHeight=窗高;
glBindFramebuffer(GL\u DRAW\u FRAMEBUFFER,0);
返回true;

那么我的问题是:这是什么原因造成的?有解决方案吗?

当我在延迟渲染器上工作时,我只是在Nividia 560ti上使用纹理进行深度和模具开发,没有任何问题。但在我的HD 4650上,我不会显示任何东西,只是一个黑屏,所以我切换到了深度和模具,这解决了我的问题。唯一的缺点是它们不能在着色器中采样。我希望这能有所帮助。

好吧,我让它工作了。问题很简单,我忘记了在球体的渲染代码中除以sizeof(float),所以它渲染得太多了,甚至没有被渲染!,但它是固定的,所以感谢所有帮助我获得更好的表现

我怀疑这是一个填充率问题,除此之外很难说。添加skybox时是否停止清除颜色/深度缓冲区?很多老资料都会告诉你,这是一种可以用于Skybox的优化,但在现代GPU(使用缓冲区压缩)上,这是一种根本不可能的优化。另外,渲染skybox的顺序是什么?要使其填充率最少,应在所有其他不透明几何体之后绘制。如果你已经这样画了,您可以先尝试绘制skybox,只是为了过分强调任何填充率限制以跟踪瓶颈。@AndonM.Coleman我将所有内容渲染到第二个帧缓冲区中,其中包含位置/漫反射/法线/texcoord Texture2D和深度+模具纹理,然后在进行照明计算后,将最终图像渲染到原始图像帧缓冲区。因此,我在“几何体传递”之前清除最终图像缓冲区一次。但我只对skybox使用漫反射纹理,但对地形我使用其他纹理。我最后一次渲染skybox实际上我试着先移动它,但那会产生更糟糕的fps。哦,哇。如果您关心性能优化,那么它有很多问题。您可以取消位置G缓冲区并从深度重建位置,并且您不希望blit帧缓冲区,除非您尝试执行MSAA解析。在大多数情况下,绘制带纹理的四边形将比
glBlitFramebuffer(…)
快得多。@AndonM.Coleman我已经用设置G-Buffer的代码更新了我的问题,希望这是您想要的!32位浮点对于除位置缓冲区之外的所有东西都是多余的。更糟糕的是,它使用32位RGB而不是RGBA。某些GPU无法处理RGB32F,需要RGBA32F。驱动程序可能会在内部将这些纹理更改为RGBA32F,并使
A
组件不可用。知道了这一点,您可能能够将一些额外的数据编码到每个缓冲区的
A
组件中,并保存1个完整的缓冲区wor
        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;