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
→ GLSLint
,Uint32BufferAttribute
→ GLSLuint
- 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