• Octahedral-encodes an array of unit-length 3D normals into a flat array of 16-bit unsigned integers (two values per normal).

    The signed-zero octahedral form maps a unit normal to a 2D coordinate in [-1, 1]; this encoder remaps that range to [0, 65535] so the output fits a single RG16UI texel per normal — half the memory cost of three unquantised floats while retaining sub-degree precision (worst-case angular error is roughly 0.001 rad), which is comfortably below the perceptual threshold for diffuse Lambert and the lower-frequency PBR terms.

    Input is read three components at a time. Non-unit inputs are normalised before encoding. The output length is two-thirds of the input length.

    The matching shader-side decode is:

    vec2 e = vec2(packed) / 65535.0 * 2.0 - 1.0;
    vec3 n = vec3(e.xy, 1.0 - abs(e.x) - abs(e.y));
    if (n.z < 0.0) n.xy = (1.0 - abs(n.yx)) * sign(n.xy);
    n = normalize(n);
    

    Parameters

    Returns Uint16Array