使用OpenGL和GLSL对性能的简单好奇

时间:2014-07-10 00:21:39

标签: opengl glsl shader

我使用OpenGL和GLSL开发了一个小型3D引擎。

这是渲染代码的一部分:

void video::RenderBatch::Render(void)
{
    type::EffectPtr pShaderEffect = EffectManager::GetSingleton()
        .FindEffectByName(this->m_pMaterial->GetAssocEffectName());

    pShaderEffect->Bind();
    {
        ///VERTEX ATTRIBUTES LOCATIONS.
        {
            pShaderEffect->BindAttribLocation(scene::VERTEX_POSITION, "VertexPosition");
            pShaderEffect->BindAttribLocation(scene::VERTEX_TEXTURE, "VertexTexture");
            pShaderEffect->BindAttribLocation(scene::VERTEX_NORMAL, "VertexNormal");
        }
        //SEND MATRIX UNIFORMS.
        {
            glm::mat3 normalMatrix = glm::mat3(glm::vec3(this->m_ModelViewMatrix[0]),
                glm::vec3(this->m_ModelViewMatrix[1]), glm::vec3(this->m_ModelViewMatrix[2]));

            pShaderEffect->SetUniform("ModelViewProjMatrix", this->m_ModelViewProjMatrix);
            pShaderEffect->SetUniform("ModelViewMatrix", this->m_ModelViewMatrix);
            pShaderEffect->SetUniform("NormalMatrix", normalMatrix);
        }
        this->SendLightUniforms(pShaderEffect); //LIGHT MATERIALS TO BE SENT JUST ONCE */

        pShaderEffect->SendMaterialUniforms( //SEND MATERIALS IF CHANGED
            this->m_pMaterial->GetName());

        this->m_pVertexArray->Lock();
        {
            this->m_pIndexBuffer->Lock();
            {
                RenderData renderData = this->GetVisibleGeometryData();
                {
                    glMultiDrawElements(GL_TRIANGLES, (GLsizei*)&renderData.count[0], GL_UNSIGNED_INT,
                        (const GLvoid **)&renderData.indices[0], renderData.count.size());
                }
            }
            this->m_pIndexBuffer->Unlock();
        }
        this->m_pVertexArray->Unlock();
    }
    pShaderEffect->Release();
}

我注意到函数的调用' SetUniform'造成巨大的FPS损失(超过1000 FPS,没有它到+ - 65 FPS随之而来!)。只需简单调用一下这个函数即可!

这里是函数的代码' this-> SetUniform' (对于矩阵4x4):

void video::IEffectBase::SetUniform(char const *pName, glm::mat4 mat)
{
    int location = glGetUniformLocation(this->m_Handle, pName);
    if (location >= 0)
        glUniformMatrix4fv(location, 1, GL_FALSE, glm::value_ptr(mat));
}

实际上只需要调用函数> glGetUniformLocation'或者功能> glUniformMatrix4fv'足以导致FPS的这种损失。通过此功能的独特调用,超过1000 FPS到65 FPS是否正常?但是缓冲区绑定或着色器程序绑定不会产生这样的效果! (如果我评论所有' SetUniform'调用,即使所有绑定(状态更改),我仍然有超过1000 FPS!)。

因此,总结一下情况,我需要向着色器程序发送统一信息的所有函数(矩阵和材料数据等等)似乎对帧速率产生巨大影响。但是在这个例子中,我的场景只由一个独特的立方体网格组成!渲染GPU没什么可怕的!

但我不认为问题来自GPU,因为我的程序对它的影响是可笑的(根据' GPUShark'):

enter image description here

只有6%!但只是窗口的显示(没有几何形状)就足以达到6%!因此,我的立方体的渲染对GPU几乎没有任何影响。所以我认为这个问题来自CPU / GPU数据传输...我认为使用这些功能导致性能下降是正常的,但从超过1000 FPS到65 FPS是不可思议的!只是为了绘制一个简单的几何体!

有没有办法获得更好的性能,或者使用这种发送数据技术导致FPS丢失是否正常?

你怎么看?

非常感谢你的帮助!

1 个答案:

答案 0 :(得分:2)

每次需要设置制服的值时,请勿致电glGetUniformLocation。对于给定着色器,统一位置不会更改(除非您重新编译它),因此在编译着色器后查找制服一次并保存位置值以便在Render函数中使用。