版权声明:本文为 松阳 (blog.csdn.net/fansongy) 原创文章,转载必须注明出处: https://blog.csdn.net/fansongy/article/details/69949641
几何体实例化( GeometryInstancing ),是一种用于大批量重复物件渲染的GPU技术,以降低客户端和显卡端数据传输量,所谓的“一次提交,多次渲染”。简单说来就是合并DrawCall。
原理
通过
glDrawElementsInstanced(GL_TRIANGLES, indexCount, GL_UNSIGNED_INT, 0,3);
可以绘制多次几何体,这样就可以实现合并。然而不同几何体都重叠在一起了,这就需要传入一个差异性参数。然后通过glVertexAttribDivisor
来指定分组赋值规则,这就相当于for循环最后的++i
。
实现
首先先设定一个变量数组,并将它存入VBO中
float posOffsets[] = {
-1.0f,0.0f,0.0f,
0.0f,0.0f,0.0f,
1.0f,0.0f,0.0f
};
GLuint offsetVBO=CreateBufferObject(GL_ARRAY_BUFFER, sizeof(float) * 9, GL_STATIC_DRAW, posOffsets);
//get location index
offsetLocation = glGetAttribLocation(program, "offset");
绘制部分将这组VBO分组:
glBindBuffer(GL_ARRAY_BUFFER, offsetVBO);
glEnableVertexAttribArray(offsetLocation);
glVertexAttribPointer(offsetLocation, 3, GL_FLOAT, GL_FALSE, sizeof(float)*3, (void*)0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glVertexAttribDivisor(offsetLocation,1);
最后在shader中承接这组数据:
attribute vec3 pos;
attribute vec2 texcoord;
attribute vec3 normal;
attribute vec3 offset;
uniform mat4 M;
uniform mat4 V;
uniform mat4 P;
uniform mat4 NM;
varying vec3 V_Normal;
varying vec4 V_WorldPos;
varying vec2 V_Texcoord;
void main()
{
V_Normal=mat3(NM)*normal;
V_WorldPos=M*vec4(pos,1.0)+vec4(offset,1.0);
V_Texcoord=texcoord;
gl_Position=P*V*V_WorldPos;
}
这样就可以在3个不同的位置绘制相同的物体,且只占用一次DrawCall。
总结
通过 GeometryInstancing 可以在OpenGL中,实现合并Drawcall。
关注我的微信公众号,获取更多优质内容