packUnorm2x16
Takes a vec2 of normalized floats, quantizes each component to a 16-bit unsigned integer using UNORM16 (round(clamp(c, 0, 1) * 65535.0)), and packs both into a single 32-bit uint.
Core Advantages
Provides an efficient fixed-point encoding for values in the [0,1] range: two normalized float channels can be stored in one uint, reducing memory and bandwidth while preserving a linear UNORM mapping. This is ideal for G-buffer layouts, storage buffers, and texture encodings where data is naturally normalized.
Common Uses
Packing two [0,1] physical parameters (for example roughness and metallic) into a single uint in deferred or custom G-buffer setups to reduce render target size.
Storing pairs of normalized parameters in storage buffers / SSBOs (such as intensity + weight, mask A + mask B) for later decoding in compute or post-processing passes.
Quantizing already normalized data (weights, masks, normalized UV offsets, etc.) for network transfer or caching, so that the representation is compact but still linearly decodable.
Designing simple, custom 0–1 fixed-point formats where the high 16 bits hold one normalized value and the low 16 bits hold another, to be decoded with a matching UNORM2x16 scheme.
How to adjust
packUnorm2x16 itself has no extra parameters; all control lives in how you prepare its vec2 input. In practice: (1) keep the input values roughly within [0,1], since values outside this range are clamped before quantization; (2) for quantities outside [0,1], normalize them (scale/offset) before packing and apply the inverse transform when decoding; (3) UNORM16 offers 0..65535 discrete steps, which is usually enough for 0–1 parameters but still introduces quantization error—decide based on how sensitive your effect is to precision; (4) treat the uint output purely as a packed container to be written to uint buffers or textures, and only interpret it through matching UNORM unpack logic in the appropriate stage.
Code Examples
1// Pack two normalized parameters (e.g. roughness and metallic) into one uint
2const rm = vec2( roughnessNode, metalnessNode );
3
4// Quantize both components as UNORM16 and pack them into a 32-bit uint
5const packedRM = packUnorm2x16( rm );
6
7// packedRM is typically written to a uint buffer or texture
8// Later passes can decode it using the same UNORM2x16 convention to recover
9// approximate [0,1] values.