Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Packing

WGSL provides builtins to pack and unpack vectors of normalized or floating-point values into a single u32. wgsl-rs exposes all of them as free functions in wgsl_rs::std.

Pack / unpack pairs

FunctionWGSL EquivalentDescription
pack4x8snorm(v)pack4x8snormPack 4× f32 in [-1,1] into u32, 8 bits each, signed normalized.
unpack4x8snorm(u)unpack4x8snormInverse of pack4x8snorm.
pack4x8unorm(v)pack4x8unormPack 4× f32 in [0,1] into u32, 8 bits each, unsigned normalized.
unpack4x8unorm(u)unpack4x8unormInverse of pack4x8unorm.
pack2x16snorm(v)pack2x16snormPack 2× f32 in [-1,1] into u32, 16 bits each, signed normalized.
unpack2x16snorm(u)unpack2x16snormInverse of pack2x16snorm.
pack2x16unorm(v)pack2x16unormPack 2× f32 in [0,1] into u32, 16 bits each, unsigned normalized.
unpack2x16unorm(u)unpack2x16unormInverse of pack2x16unorm.
pack2x16float(v)pack2x16floatPack 2× f32 into u32 as f16 pairs.
unpack2x16float(u)unpack2x16floatInverse of pack2x16float.

Inputs are Vec4f / Vec2f for the pack functions; outputs are u32. The unpack functions take u32 and return the corresponding vector.

Rounding behavior

The pack functions round normalized floats to the nearest representable integer using round-to-nearest-even, matching WGSL. Values outside the normalized range are clamped.

Example

#![allow(unused)]
fn main() {
#[wgsl]
pub mod packing_example {
    use wgsl_rs::std::*;

    pub fn encode_tangent(t: Vec4f) -> u32 {
        pack4x8snorm(t)
    }

    pub fn decode_tangent(packed: u32) -> Vec4f {
        unpack4x8snorm(packed)
    }
}
}

CPU behavior

The CPU implementations use the same rounding and clamping as WGSL, so pack followed by unpack returns a value within one ULP of the original. This makes packing safe to exercise in unit tests.