Instancing Sample
Description
This sample demonstrates how instancing techniques can be used to speed up drawing operations for scenes that consist of many copies of the same object rendered with slight differences.
APIs Used
- glDrawElementsInstanced (or glDrawElementsInstancedARB, or glDrawElementsInstancedNV)
- glVertexAttribDivisor (or glVertexAttribDivisorARB, or glVertexAttribDivisorNV)
- GL_ARB_instanced_arrays [optional]
- GL_NV_draw_instanced [optional]
Shared User Interface
The Graphics samples all share a common app framework and certain user interface elements, centered around the "Tweakbar" panel on the left side of the screen which lets you interactively control certain variables in each sample.
To show and hide the Tweakbar, simply click or touch the triangular button positioned in the top-left of the view.
Technical Details
This sample demonstrates how instancing techniques can be used to speed up drawing operations for scenes that consist of many copies of the same object rendered with slight differences.
The key message here is if your scene is cpu/driver limited by the sheer volume of draw calls and/or uniform updates, using hardware instancing is the easiest way to overcome those performance bottlenecks.
Render Modes
There are two different visuals that can be rendered via the Render Mode UI, each with its own set of control variables per instance:
-
Boxes
Draws a 3D grid of textured and animated cubes. Each cube has the following unique per instance attributes:
- 3D Position
- Rotation around the Y axis
- Color shade into a palette of 6 shades
-
Grass
Draws a rectangular (2D) patch of grass blades. Each grass blade has the following unique per instance attributes:
- 2D Position
- Rotation around the Y axis
- Color index used to choose one of 6 color variations for the grass blades
Instancing Modes
The sample has three different, selectable Instancing Modes that show different techniques for rendering instances, each with different performance (from slowest to fastest):
-
No Instancing
Each instance of the object is drawn individually.
- Two calls to
glUniform3fv
to set the attributes for the current instance - One call to
glDrawElements
to render the current instance
- Two calls to
-
Shader Instancing
Objects are drawn in batches with each batch containing up to 100 instances.
- Two calls to
glUniform3fv
to set the attributes for the current batch of instances - One call to
glDrawElements
to render the current batch of instance
In order to support drawing 100 instances of the object the sample creates a vertex buffer object that contains the vertices of 100 copies of the object. The data for each vertex is extended to additionally contain an instance id. This id is then used to load per instance attributes from an array of uniform shaders variables to adjust position, rotation and color of each instance.
Further on, in addition to the vertex buffer object, a buffer is created that contains the indices for the 100 copies of the original index buffer.
- Two calls to
-
Hardware Instancing
Objects are drawn using just one call to
glDrawElementsInstanced()
(or if not availableglDrawElementsInstancedARB()
orglDrawElementsInstancedNV()
).To setup this draw call additional per instance vertex attributes are setup by two calls to each
glEnableVertexAttribArray
,glVertexAttribPointer
andglVertexAttribDivisorARB/NV
. This setup does bring in per instance data as additional per vertex attributes to the vertex shader.