Compresses normal vectors (or any 3D unit vector) using Octahedron encoding.
This lossy compression scheme is able to achieve a compression ratio as high as 6:1 with an average error rate of less than 1 degree, depending on which representation is chosen.
Example:
let normal = ;
let encoded = encode;
let decoded = encoded.decode;
assert_eq!;
Why compress my normals?
It is common for 3D renderers to be bottlenecked by memory bandwidth, such as when loading normals from VRAM for high-poly meshes to supply to your vertex shader. A smaller memory footprint for your normals corresponds to memory bandwidth savings and higher FPS in such scenarios.
How bad is 1 degree of error?
The teapot example generates a reference visual and contains the wgsl code required to decode the vector in a shader.
Standard [f32; 3] representation
Packed into a [u8; 2]
As a video
The skybox used in the example is the work of Emil Persson, aka Humus. http://www.humus.name