我使用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'):
只有6%!但只是窗口的显示(没有几何形状)就足以达到6%!因此,我的立方体的渲染对GPU几乎没有任何影响。所以我认为这个问题来自CPU / GPU数据传输...我认为使用这些功能导致性能下降是正常的,但从超过1000 FPS到65 FPS是不可思议的!只是为了绘制一个简单的几何体!
有没有办法获得更好的性能,或者使用这种发送数据技术导致FPS丢失是否正常?
你怎么看?
非常感谢你的帮助!
答案 0 :(得分:2)
每次需要设置制服的值时,请勿致电glGetUniformLocation
。对于给定着色器,统一位置不会更改(除非您重新编译它),因此在编译着色器后查找制服一次并保存位置值以便在Render
函数中使用。