我正在编写自己的渲染引擎。目前我正在研究地形。
我使用glDrawArraysInstanced
渲染地形。地形是由很多"块组成的。每个块都是一个四边形,它也是绘制调用的一个实例。然后在曲面细分着色器中对每个四边形进行细分。对于我的着色器输入,我使用 VBOs ,实例化VBO (使用顶点属性除数)和纹理缓冲区。这是我的一个着色器的一个简单示例:
#version 410 core
layout (location = 0) in vec3 perVertexVector; // VBO attribute
layout (location = 1) in vec3 perInstanceVector; // VBO instanced attribute
uniform samplerBuffer someTextureBuffer; // texture buffer
out vec3 outputVector;
void main()
{
// some processing of the inputs;
outputVector = something...whatever...;
}
一切正常,我没有错误。它呈现在 60-70 FPS 附近。但今天我改变了代码,我不得不将所有实例化的VBO更改为纹理缓冲区。由于某种原因,性能增加了一倍,它运行在 120-160 FPS!(有时甚至更多!)我没有改变任何其他东西,我只是创建了更多的纹理缓冲区并使用它们代替所有实例化属性。
这是我用于创建着色器实例化属性的代码(简化为可读版本):
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, size, buffer, GL_DYNAMIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0);
glEnableVertexAttribArray(0);
glVertexAttribDivisor(0, 1); // this makes the buffer instanced
这是我创建纹理缓冲区的简化代码:
glBindTexture(GL_TEXTURE_BUFFER, textureVBO);
glTexBuffer(GL_TEXTURE_BUFFER, GL_RGB32F, VBO);
我不认为我做错了什么因为一切正常。它只是性能...我会假设属性比纹理快,但我得到了相反的结果,我真的很惊讶纹理缓冲区比属性快两倍以上。
但还有一件事我不明白。
我实际上两次调用地形(glDrawArraysInstanced
)的渲染函数。第一次是渲染地形,第二次是使用不同的水反射变换矩阵将其渲染到FBO。当我只渲染一次(没有反射)并且我使用实例属性时,我得到 90 FPS ,这比我之前提到的60 FPS快一点。
但是!当我只渲染一次并使用纹理缓冲区时,差异非常小。它的运行速度与我渲染两次(大约120-150 fps)时一样快!
我想知道它是否使用某种缓存或其他东西,但它对我没有任何意义,因为顶点用两个渲染调用中的每一个的不同矩阵进行变换,因此着色器输出完全不同的结果。 / p>
我真的很感激这个问题的一些解释:
为什么纹理缓冲区比实例属性更快?
以下是我的问题的摘要,以便更好地理解:
我唯一能做的就是在我的glsl代码中更改这些行:
layout (location = 1) in vec3 perInstanceVector; // VBO instanced attribute
outputVector = perInstanceVector;
到此:
uniform samplerBuffer textureBuffer; // texture buffer which has the same data as the previous VBO instanced attribute
outputVector = texelFetch(textureBuffer, gl_InstanceID).xyz
一切都和以前完全一样,但在性能方面却快了两倍。
答案 0 :(得分:0)
我看到3个可能的原因:
您尝试过使用不同数量的原语吗?还是尝试使用计时器?