GPU Instancing in GL3

GPU Instancing using GL3

The GL3 engine allows for a new feature called GPU Instancing. This technique allows an object to be drawn multiple times using hardware instancing techniques, meaning all the instances are drawn with a single GL draw call. More specifically, the instances are grouped based on textures, so all instances with the same texture binding are grouped together and drawn with a single call.

Supported Objects

Currently instancing can be performed using either jit.gl.multiple or jit.gl.mesh. Each method has different requirements, advantages and limitations.

Instancing with jit.gl.multiple

When using the GL3 engine, jit.gl.multiple draws all copies of the target using GPU instancing. Functionally the object works just as it did with GL2 with the exception that arbitrary OB3D attributes in the glparams list (e.g., attr.rad_minor) are currently not supported. For this functionality you will need to revert to the gl2 engine.

NOTES:

  • The GPU instancing technique requires that the instance parameter values be sent to the shader as attributes, and a special shader must be generated to handle them. It is possible to bind a custom shader with jit.gl.shader, however it must conform to a specific format.
  • To achieve maximal performance, back-face culling (@cull_face 1) and triangular grid drawing (@gridmode 1) are recommended for all targeted objects (i.e., jit.gl.gridshape or jit.gl.mesh). When these settings are not used, the extra load on the GPU may result in lower frame rates than experienced in gl2, particularly on older hardware.

Instancing with jit.gl.mesh

The jit.gl.mesh object can also be used for instancing under gl3. This allows you to draw many copies of the gl.mesh without using a gl.multiple, thereby giving more control over which vertex-buffers are instance attributes (the vertex attributes that have unique values for each instance). This is made possible by the addition of 4 new vertex attribute buffers that allow you to manipulate the vertex buffer via shaders and requires using the new jit.gl.buffer object. The vertex buffers are then accessed via a custom shader that is bound to jit.gl.mesh.

Setting vertex_attr buffers in jit.gl.buffer

You can send up to 4 buffers to jit.gl.mesh and access them as inputs in your vertex shader using jit.gl.buffer The @instanced attribute must be enabled (set to 1) and the @type attribute should be set to vertex_attr. To bind multiple vertex attribute buffers, you must specify the buffer index in the form @type vertex_attr0..3. e.g.: jit.gl.buffer @type vertex_attr0 @instanced 1, jit.gl.buffer @type vertex_attr1 @instanced 1, etc.

Note that the index determines the order in which the buffers are applied and can be critical for certain types of operations (like determining current position before applying velocity change). When using a single input, no index is necessary and type can simply be set as `@type vertex_attr`.

Accessing vertex_attr buffers in shaders

To access the buffers in the shader, create a param and specify state as VERTEX_ATTR0..3, e.g.:

<param name="flock_position" type="vec3" state="VERTEX_ATTR0" />
      <param name="flock_velocity" type="vec3" state="VERTEX_ATTR1" />

and in the body of the vertex shader:

in vec3 flock_position;
      in vec3 flock_velocity;

See Also

Name Description
GL3 Package Topics GL3 Package Topics
jit.gl.buffer
jit.gl.mesh Generate GL geometry from matrices
jit.gl.multiple Create multiple object instances