我正在编写自己的渲染引擎。目前,我正在地形上。我使用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快一点。
BUT!
当我仅渲染一次并且使用纹理缓冲区时,差异确实很小。它的运行速度与我两次渲染时一样快(约120-150 fps)! 我想知道它是否使用某种缓存或某种方式,但是对我来说没有任何意义,因为两个渲染调用中的每个顶点都是使用不同的矩阵进行变换的,因此着色器输出的结果完全不同。为什么纹理缓冲区比实例属性快?
摘要
,以便更好地理解:我唯一要做的就是在我的glsl代码中change
这些行: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
一切都像以前一样工作,但性能提高了一倍。