LYGIA Shader Library

unpack (lygia/math/unpack)

Unpack a 3D vector into a float. Default base is 256.0

Use:

<float> unpack(<vec3> v, [, <float> base])

Check it on Github


#ifndef UNPACK_FNC
#define UNPACK_FNC unpack256
#endif 

// https://github.com/mrdoob/three.js/blob/acdda10d5896aa10abdf33e971951dbf7bd8f074/src/renderers/shaders/ShaderChunk/packing.glsl
#ifndef CONST_PACKING
#define CONST_PACKING
const float PackUpscale = 256. / 255.; // fraction -> 0..1 (including 1)
const float UnpackDownscale = 255. / 256.; // 0..1 -> fraction (excluding 1)
const vec3 PackFactors = vec3( 256. * 256. * 256., 256. * 256.,  256. );
const vec4 UnpackFactors = UnpackDownscale / vec4( PackFactors, 1. );
const float ShiftRight8 = 1. / 256.;
#endif

#ifndef FNC_UNPACK
#define FNC_UNPACK

float unpack8(vec3 v) {
    vec3 f = vec3( 8.0, 8.0 * 8.0, 8.0 * 8.0 * 8.0 );
    return dot(v, f) / 512.0;
}

float unpack16(vec3 v) {
    vec3 f = vec3( 16.0, 16.0 * 16.0, 16.0 * 16.0 * 16.0 );
    return dot(v, f) / 4096.0;
}

float unpack32(vec3 v) {
    vec3 f = vec3( 32.0, 32.0 * 32.0, 32.0 * 32.0 * 32.0 );
    return dot(v, f) / 32768.0;
}

float unpack64(vec3 v) {
    vec3 f = vec3( 64.0, 64.0 * 64.0, 64.0 * 64.0 * 64.0 );
    return dot(v, f) / 262144.0;
}

float unpack128(vec3 v) {
    vec3 f = vec3( 128.0, 128.0 * 128.0, 128.0 * 128.0 * 128.0 );
    return dot(v, f) / 2097152.0;
}

float unpack256(vec3 v) {
    vec3 f = vec3( 256.0, 256.0 * 256.0, 256.0 * 256.0 * 256.0 );
    return dot(v, f) / 16581375.0;
}

float unpack(vec3 v, float base) {
    float base3 = base * base * base;
    vec3 f = vec3( base, base * base, base3);
    return dot(v, f) / base3;
}

float unpack(vec3 v) {
    return UNPACK_FNC(v);
}

// https://github.com/mrdoob/three.js/blob/acdda10d5896aa10abdf33e971951dbf7bd8f074/src/renderers/shaders/ShaderChunk/packing.glsl
float unpack( const in vec4 v ) {
    return dot( v, UnpackFactors );
}

#endif

Use:

<float> unpack(<float3> value [, <float> base])

Check it on Github


#ifndef UNPACK_FNC
#define UNPACK_FNC unpack256
#endif 

// https://github.com/mrdoob/three.js/blob/acdda10d5896aa10abdf33e971951dbf7bd8f074/src/renderers/shaders/ShaderChunk/packing.glsl
#ifndef CONST_PACKING
#define CONST_PACKING
const float PackUpscale = 256. / 255.; // fraction -> 0..1 (including 1)
const float UnpackDownscale = 255. / 256.; // 0..1 -> fraction (excluding 1)
const float3 PackFactors = float3( 256. * 256. * 256., 256. * 256.,  256. );
const float4 UnpackFactors = UnpackDownscale / float4( PackFactors, 1. );
const float ShiftRight8 = 1. / 256.;
#endif

#ifndef FNC_UNPACK
#define FNC_UNPACK

float unpack8(float3 v) {
    float3 f = float3( 8.0, 8.0 * 8.0, 8.0 * 8.0 * 8.0 );
    return dot(v, f) / 512.0;
}

float unpack16(float3 v) {
    float3 f = float3( 16.0, 16.0 * 16.0, 16.0 * 16.0 * 16.0 );
    return dot(v, f) / 4096.0;
}

float unpack32(float3 v) {
    float3 f = float3( 32.0, 32.0 * 32.0, 32.0 * 32.0 * 32.0 );
    return dot(v, f) / 32768.0;
}

float unpack64(float3 v) {
    float3 f = float3( 64.0, 64.0 * 64.0, 64.0 * 64.0 * 64.0 );
    return dot(v, f) / 262144.0;
}

float unpack128(float3 v) {
    float3 f = float3( 128.0, 128.0 * 128.0, 128.0 * 128.0 * 128.0 );
    return dot(v, f) / 2097152.0;
}

float unpack256(float3 v) {
    float3 f = float3( 256.0, 256.0 * 256.0, 256.0 * 256.0 * 256.0 );
    return dot(v, f) / 16581375.0;
}

float unpack(float3 v, float base) {
    float base3 = base * base * base;
    float3 f = float3( base, base * base, base3);
    return dot(v, f) / base3;
}

float unpack(float3 v) {
    return UNPACK_FNC(v);
}

// https://github.com/mrdoob/three.js/blob/acdda10d5896aa10abdf33e971951dbf7bd8f074/src/renderers/shaders/ShaderChunk/packing.glsl
float unpack( const in float4 v ) {
    return dot( v, UnpackFactors );
}

#endif

Check it on Github


// https://github.com/mrdoob/three.js/blob/acdda10d5896aa10abdf33e971951dbf7bd8f074/src/renderers/shaders/ShaderChunk/packing.glsl

const PackUpscale: f32 = 256. / 255.; // fraction -> 0..1 (including 1)
const UnpackDownscale: f32 = 255. / 256.; // 0..1 -> fraction (excluding 1)
const PackFactors = vec3f( 256. * 256. * 256., 256. * 256.,  256. );
const UnpackFactors = UnpackDownscale / vec4f( PackFactors, 1. );
const ShiftRight8: f32 = 1. / 256.;

fn unpack8(vec3 v) -> f32 {
    let f = vec3( 8.0, 8.0 * 8.0, 8.0 * 8.0 * 8.0 );
    return dot(v, f) / 512.0;
}

fn unpack16(vec3 v) -> f32 {
    let f = vec3( 16.0, 16.0 * 16.0, 16.0 * 16.0 * 16.0 );
    return dot(v, f) / 4096.0;
}

fn unpack32(vec3 v) -> f32 {
    let f = vec3( 32.0, 32.0 * 32.0, 32.0 * 32.0 * 32.0 );
    return dot(v, f) / 32768.0;
}

fn unpack64(vec3 v) -> f32 {
    let f = vec3( 64.0, 64.0 * 64.0, 64.0 * 64.0 * 64.0 );
    return dot(v, f) / 262144.0;
}

fn unpack128(vec3 v) -> f32 {
    let f = vec3( 128.0, 128.0 * 128.0, 128.0 * 128.0 * 128.0 );
    return dot(v, f) / 2097152.0;
}

fn unpack256(vec3 v) -> f32  {
    let f = vec3( 256.0, 256.0 * 256.0, 256.0 * 256.0 * 256.0 );
    return dot(v, f) / 16581375.0;
}

fn unpack(v: vec3f, base: f32) -> f32 {
    let base3 = base * base * base;
    let f = vec3( base, base * base, base3);
    return dot(v, f) / base3;
}

fn unpack(v: vec3f) -> f32 { return unpack256(v); }

// https://github.com/mrdoob/three.js/blob/acdda10d5896aa10abdf33e971951dbf7bd8f074/src/renderers/shaders/ShaderChunk/packing.glsl
fn unpack4(v: vec4f ) -> f32 { return dot( v, UnpackFactors ); }

Dependencies:

Use:

<float> unpack(<float3> value [, <float> base])

Check it on Github



#ifndef UNPACK_FNC
#define UNPACK_FNC unpack256
#endif 

#ifndef FNC_UNPACK
#define FNC_UNPACK

inline __host__ __device__ float unpack8(const float3& value) {
    float3 factor = make_float3( 8.0f, 8.0f * 8.0f, 8.0f * 8.0f * 8.0f );
    return dot(value, factor) / 512.0f;
}

inline __host__ __device__ float unpack16(const float3& value) {
    float3 factor = make_float3( 16.0f, 16.0f * 16.0f, 16.0f * 16.0f * 16.0f );
    return dot(value, factor) / 4096.0f;
}

inline __host__ __device__ float unpack32(const float3& value) {
    float3 factor = make_float3( 32.0f, 32.0f * 32.0f, 32.0f * 32.0f * 32.0f );
    return dot(value, factor) / 32768.0f;
}

inline __host__ __device__ float unpack64(const float3& value) {
    float3 factor = make_float3( 64.0f, 64.0f * 64.0f, 64.0f * 64.0f * 64.0f );
    return dot(value, factor) / 262144.0f;
}

inline __host__ __device__ float unpack128(const float3& value) {
    float3 factor = make_float3( 128.0f, 128.0f * 128.0f, 128.0f * 128.0f * 128.0f );
    return dot(value, factor) / 2097152.0f;
}

inline __host__ __device__ float unpack256(const float3& value) {
    float3 factor = make_float3( 256.0f, 256.0f * 256.0f, 256.0f * 256.0f * 256.0f );
    return dot(value, factor) / 16581375.0f;
}

inline __host__ __device__ float unpack(const float3& value, float base) {
    float base3 = base * base * base;
    float3 factor = make_float3( base, base * base, base3);
    return dot(value, factor) / base3;
}

inline __host__ __device__ float unpack(const float3& value) {
    return UNPACK_FNC(value);
}
#endif

License

LYGIA is dual-licensed under the Prosperity License and the Patron License for sponsors and contributors.

Sponsors and contributors are automatically added to the Patron License and they can ignore the any non-commercial rule of the Prosperity Licensed software (please take a look to the exception).

It's also possible to get a permanent comercial license hook to a single and specific version of LYGIA.

Get the latest news and releases

Sign up for the news letter bellow, joing the LYGIA's channel on Discord or follow the Github repository