Integer Attributes in WebGL2

Demonstrating float vs integer attributes in custom shaders

Integer Attributes in WebGL2

WebGL2 introduces support for integer vertex attributes through the vertexAttribIPointer function. This allows passing integer data directly to shaders without automatic conversion to floats, enabling precise integer operations and better performance for specific use cases.

Key Differences from WebGL1:

  • WebGL1: All attributes converted to floats automatically
  • WebGL2: True integer attributes preserved with vertexAttribIPointer
  • Precision: No floating-point precision loss for large integers

Three.js Implementation:

  • Automatic Detection: Three.js detects integer buffer attributes
  • Type Mapping: Int32BufferAttribute → GLSL int, Uint32BufferAttribute → GLSL uint
  • No Interpolation: Integer attributes must use flat qualifier

Use Cases & Benefits:

  • Skeletal Animation: Precise bone indices without rounding errors
  • Texture Atlases: Exact texture/material ID lookup
  • Bit Operations: GLSL 3.0 ES supports bitwise operations on integers
  • Instance IDs: Efficient instanced rendering with unique identifiers
  • Memory Efficiency: Smaller data types (BYTE: 1 byte, SHORT: 2 bytes vs FLOAT: 4 bytes)

Example Usage:

// JavaScript - Three.js automatically uses vertexAttribIPointer
const colorIndices = new Int32Array([0, 1, 2]);
geometry.setAttribute('colorIndex', 
  new THREE.Int32BufferAttribute(colorIndices, 1));

// GLSL Vertex Shader (GLSL 3.0 ES)
in int colorIndex;
flat out int vColorIndex;  /* 'flat' prevents interpolation */

void main() {
  vColorIndex = colorIndex;  /* Exact integer value */
}

// GLSL Fragment Shader
flat in int vColorIndex;  /* Receives discrete integer */

void main() {
  /* Use integer for palette lookup, bit operations, etc. */
  vec3 color = palette[vColorIndex];
}

Supported Integer Types:

  • gl.BYTE / gl.UNSIGNED_BYTE (1 byte)
  • gl.SHORT / gl.UNSIGNED_SHORT (2 bytes)
  • gl.INT / gl.UNSIGNED_INT (4 bytes)

Requirements:

  • WebGL2 context (automatic in modern browsers)
  • GLSL 3.0 ES shaders (glslVersion: THREE.GLSL3)
  • Three.js r72+ with integer attribute support

Visual Comparison:

  • Left (Float): Smooth color gradients via GPU interpolation
  • Right (Integer): Discrete colors from palette lookup, no interpolation

Performance Notes:

  • Bandwidth: Reduced memory usage with smaller integer types
  • Precision: No conversion overhead or precision loss
  • Operations: Direct bitwise operations in shaders