Instancing in computer graphics refers to the technique of using a single set of geometry, shader, and textures to draw multiple copies of an object in a scene. It is used to reduce the number of draw calls needed to render a scene, which can significantly improve the performance of the rendering pipeline.
Why it matters
One of the key benefits of instancing is that it allows the GPU to batch together multiple draw calls into a single call, reducing the overhead of issuing multiple draw commands. This is especially useful when rendering a large number of similar objects — grass, trees, particles — which can quickly add up and strain the GPU.
Without instancing, rendering 1000 trees means 1000 separate draw calls, each with its own state setup, buffer binding, and driver overhead. With instancing, that becomes one call.
Basic Example
Drawing 100 instances of the same mesh:
// Bind your VAO, then:
glDrawArraysInstanced(GL_TRIANGLES, 0, vertexCount, 100);
The GPU executes the vertex shader 100 times per vertex, with each run identified by gl_InstanceID.
Using gl_InstanceID in the Shader
You can use the instance ID in the vertex shader to offset each instance:
// Vertex shader
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aOffset; // per-instance offset
void main() {
vec3 pos = aPos + aOffset * float(gl_InstanceID);
gl_Position = uMVP * vec4(pos, 1.0);
}
Instanced Vertex Attributes
A better approach is instanced vertex attributes with glVertexAttribDivisor. This lets you provide a per-instance buffer that advances once per instance instead of once per vertex:
// Set up per-instance offset buffer
glBindBuffer(GL_ARRAY_BUFFER, instanceVBO);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
// This is the key line: advance attribute once per instance, not per vertex
glVertexAttribDivisor(1, 1);
Now each instance reads its own offset from the buffer, and you can place thousands of objects with a single draw call.
Applications
Instancing shows up everywhere: foliage rendering, particle systems, crowd simulation, repeated architectural elements, shadow casters. Whenever you have many objects sharing the same mesh — instancing is the answer.