实例化(instancing)或者多实例渲染(instancd rendering)是一种连续执行多条相同渲染命令的方法。并且每个命令的所产生的渲染结果都会有轻微的差异。是一种非常有效的,实用少量api调用来渲染大量几何体的方法。OpenGL提供多种机制,允许着色器对不同渲染实例赋予不同的顶点属性。
几个简单的多实例渲染命令:
1、void glDrawArraysInstanced( GLenum mode, GLint first, GLsizei count, GLsizei primCount )
该函数是glDrawArrays()的多实例版本,参数完全等价,只是多了个primCount,该参数用于设置渲染实例个数。
2、void glDrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, void* indices, GLsizei primcount )
该函数是glDrawElements()的多实例版本,同样只是多了个primCount参数而已,同样是用于设置渲染实例个数。
3、void glDrawElementsInstancedBaseVertex( GLenum mode, GLsizei count, GLenum type, const void* indices, GLsizei instanceCount, GLuint baseVertex )
该函数是glDrawElementsBaseVertex()的多实例版本,instanceCount表示渲染的实例数目。
多实例渲染顶点属性控制:
1、void glVertexAttribDivisor( GLenum index, GLuint divisor )
index对应于着色器中输入变量的location。divisor:表示顶点属性的更新频率,每隔多少个实例将重新设置实例的该属性,例如设置为1,那么每个实例的属性都不一样,设置为2则每两个实例相同,3则每三个实例改变属性。而该属性的属性数组大小将为(instance/divisor),instance为之前设置的渲染实例数(primCount),假设在多实例渲染中改变实例的颜色,设divisor为2,instance为100,颜色数组至少为100/2 = 50组rgba数据,才能保证每个实例都有自己的颜色值,不然将是黑漆漆的。最后如果divisor设置为0,将代表是非实例化,渲染的结果是,所有实例都是黑漆漆的,可能这个黑漆漆的结果也不是必然的,我猜想的是这时候着色器的输入变量vec4 color为默认的(0.0,0.0,0.0,1.0)并没有设置它的值,所以是黑色的。
顶点着色器分析:
#version 410
//输入变量position,顶点坐标
layout (location = 0) in vec4 position;
//normal顶点法线计算
layout (location = 1) in vec3 normal;
//顶点颜色
layout (location = 2) in vec4 color;