unpackHalf2x16
Treats a 32-bit uint as two concatenated 16-bit half-precision floats, unpacks it, and returns a vec2 containing the corresponding 32-bit float values.
Core Advantages
Designed to pair with packHalf2x16, it lets you store two half-precision floats in a single uint (in buffers or textures) and later conveniently reconstruct them as a vec2 of regular floats. The actual float16 unpack implementation is provided by the backend via builder.getFloatUnpackingMethod('float16'), so you do not need to write bit manipulation or worry about backend-specific details.
Common Uses
In a previous pass, pack roughness + metallic into a uint using packHalf2x16, then in a lighting or post-processing pass, decode them back to a vec2 using unpackHalf2x16.
Reading compressed half-precision vectors from storage buffers / SSBOs (such as velocity, noise parameters, etc.) and unpacking them into vec2 for compute or shading.
Sampling from custom textures or lookup tables that store two scalar channels in half precision and decoding them to full floats at use time.
Combining with other pack/unpack nodes to build a custom compressed G-buffer or effect data buffer where some channels use float16 and others use UNORM / SNORM encodings.
How to adjust
unpackHalf2x16 itself exposes no knobs; correctness depends entirely on the uint input being encoded as a float16 pair compatible with packHalf2x16. In practice: (1) always use it together with the matching packHalf2x16 or an equivalent float16 encoder so that the layout is consistent; (2) ensure the input uint actually contains half2x16 data—feeding UNORM or unrelated bit patterns will produce meaningless results; (3) remember that half precision implies quantization and limited dynamic range, so the reconstructed values are approximations and are best used for tolerant or normalized data; (4) when designing your pipeline, clearly designate which uint channels carry “half2” payloads to avoid mixing different packing formats and making debugging difficult.
Code Examples
1// In a previous pass: pack two float parameters into a single uint (example)
2const rm = vec2( roughnessNode, metalnessNode );
3const packedRM = packHalf2x16( rm );
4
5// In the current pass: read the packed uint from some source (buffer/texture)
6const loadedPackedRM = packedRM; // Here we reuse the same node for illustration
7
8// Unpack it back to a vec2 of floats
9const decodedRM = unpackHalf2x16( loadedPackedRM );
10
11// Split into individual parameters
12const decodedRoughness = decodedRM.x;
13const decodedMetalness = decodedRM.y;
14
15material.roughnessNode = decodedRoughness;
16material.metalnessNode = decodedMetalness;