WebGL
Khronos
 

WebGL WEBGL_multi_draw_instanced_base_vertex_base_instance Extension Draft Specification

Name

WEBGL_multi_draw_instanced_base_vertex_base_instance

Contact

WebGL working group (public_webgl 'at' khronos.org)

Contributors

Contributors to the ANGLE_base_vertex_base_instance specification

Contributors to the WEBGL_multi_draw specification

Members of the WebGL working group

Version

Last modified date: July 28, 2020
Revision: 5

Number

WebGL extension #47

Dependencies

Written against the WebGL API 2.0 specification.

Implementations must also support the WEBGL_multi_draw extension.

Implementations must also support the WEBGL_draw_instanced_base_vertex_base_instance extension.

Overview

This extension exposes the MultiDrawArraysInstancedBaseInstanceANGLE and MultiDrawElementsInstancedBaseVertexBaseInstanceANGLE entrypoints as multiDrawArraysInstancedBaseInstanceWEBGL and multiDrawElementsInstancedBaseVertexBaseInstanceWEBGL. In addition the vertex shader builtins gl_BaseVertex and gl_BaseInstance are added. The implementation must validate the arrays and indices referenced by multiDrawArraysInstancedBaseInstanceWEBGL and multiDrawElementsInstancedBaseVertexBaseInstanceWEBGL, similarly to how indices referenced by drawArrays and drawElements are validated according to section Enabled Vertex Attributes and Range Checking and Range Checking of the WebGL specification. Although the extension is named WEBGL_multi_draw_instanced_base_vertex_base_instance, the extension must be enabled with the #extension GL_ANGLE_base_vertex_base_instance directive, as shown in the sample code, to use the extension in a shader. Likewise the shading language preprocessor #define GL_ANGLE_base_vertex_base_instance will be defined to 1 if the extension is supported.

The baseVertex functionality could effectly help reduce CPU overhead with static batching and text rendering in game engine implementations.

The baseInstance functionality could make instanced arrays more useful as they could start instancing from a particular point in the buffer.

The multi draw functionality could help reduce draw call overhead by allowing better batching.

When this extension is enabled:

IDL

[NoInterfaceObject]
interface WEBGL_multi_draw_instanced_base_vertex_base_instance {
  void multiDrawArraysInstancedBaseInstanceWEBGL(
      GLenum mode,
      (Int32Array or sequence<GLint>) firstsList, GLuint firstsOffset,
      (Int32Array or sequence<GLsizei>) countsList, GLuint countsOffset,
      (Int32Array or sequence<GLsizei>) instanceCountsList, GLuint instanceCountsOffset,
      (Uint32Array or sequence<GLuint>) baseInstancesList, GLuint baseInstancesOffset,
      GLsizei drawCount
  );
  void multiDrawElementsInstancedBaseVertexBaseInstanceWEBGL(
      GLenum mode,
      (Int32Array or sequence<GLsizei>) countsList, GLuint countsOffset,
      GLenum type,
      (Int32Array or sequence<GLsizei>) offsetsList, GLuint offsetsOffset,
      (Int32Array or sequence<GLsizei>) instanceCountsList, GLuint instanceCountsOffset,
      (Int32Array or sequence<GLint>) baseVerticesList, GLuint baseVerticesOffset,
      (Uint32Array or sequence<GLuint>) baseInstancesList, GLuint baseInstancesOffset,
      GLsizei drawCount
  );
};
  

New Functions

void multiDrawArraysInstancedBaseInstanceWEBGL(GLenum mode, (Int32Array or sequence<GLint>) firstsList, GLuint firstsOffset, (Int32Array or sequence<GLsizei>) countsList, GLuint countsOffset, (Int32Array or sequence<GLsizei>) baseInstancesList, GLuint baseInstancesOffset, GLsizei drawCount)
void multiDrawElementsInstancedBaseVertexBaseInstanceWEBGL(GLenum mode, (Int32Array or sequence<GLsizei>) countsList, GLuint countsOffset, GLenum type, (Int32Array or sequence<GLsizei>) offsetsList, GLuint offsetsOffset, (Int32Array or sequence<GLsizei>) instanceCountsList, GLuint instanceCountsOffset, (Int32Array or sequence<GLint>) baseVerticesList, GLuint baseVerticesOffset, (Uint32Array or sequence<GLuint>) baseInstancesList, GLuint baseInstancesOffset, GLsizei drawCount)

Sample Code

var ext = gl.getExtension("WEBGL_multi_draw_instanced_base_vertex_base_instance");

{
  // multiDrawArraysInstancedBaseInstance variant.
  let firsts = new Int32Array(...);
  let counts = new Int32Array(...);
  let instanceCounts = new Int32Array(...);
  let baseInstances = new Uint32Array(...);
  ext.multiDrawArraysInstancedBaseInstanceWEBGL(
      gl.TRIANGLES, first, 0, counts, 0, instanceCounts, 0, baseInstances, 0, counts.length);
}

{
  // multiDrawElementsInstancedBaseVertexBaseInstance variant.
  // Assumes that the indices which have been previously uploaded to the
  // ELEMENT_ARRAY_BUFFER are to be treated as UNSIGNED_SHORT.
  let counts = new Int32Array(...);
  let offsets = new Int32Array(...);
  let instanceCounts = new Int32Array(...);
  let baseVertices = new Int32Array(...);
  let baseInstances = new Uint32Array(...);
  ext.multiDrawElementsInstancedBaseVertexBaseInstanceWEBGL(
      gl.TRIANGLES, counts, 0, gl.UNSIGHNED_SHORT,
      offsets, 0, instanceCounts, 0, baseVertices, 0, baseInstances, 0,
      counts.length);
}
    
#version 300 es
#extension GL_ANGLE_base_vertex_base_instance : require
void main() {
    gl_Position = vec4(gl_BaseVertex, gl_InstanceID + gl_BaseInstance, 0, 1);
}
    

Conformance Tests

Security Considerations

The multi-draw-base-vertex-base-instance-draw APIs are subject to all of the same rules regarding out-of-range array accesses as the core WebGL APIs.

Issues

Revision History

Revision 1, 2019/08/28

Revision 2, 2019/09/25

Revision 3, 2020/06/26

Revision 4, 2020/07/14

Revision 5, 2020/07/28