Skip to content

Compresses normal vectors (or any 3D unit vector) using Octahedron encoding

License

Notifications You must be signed in to change notification settings

Davidster/normal_pack

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

34 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Compresses normal vectors (or any 3D unit vector) using Octahedron encoding.

Crates.io Documentation License: MIT

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 = [-0.5082557, 0.54751796, 0.6647558];

let encoded = normal_pack::EncodedUnitVector3U8::encode(normal);
let decoded = encoded.decode();

assert_eq!(decoded, [-0.52032965, 0.5473598, 0.6554802]);

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

teapot_packed_u8

Packed into a [u8; 2]

teapot_no_packing

As a video

normal_pack_error.mp4

The skybox used in the example is the work of Emil Persson, aka Humus. http://www.humus.name

About

Compresses normal vectors (or any 3D unit vector) using Octahedron encoding

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages