Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Performance question #1

Open
dy opened this issue Feb 7, 2016 · 2 comments
Open

Performance question #1

dy opened this issue Feb 7, 2016 · 2 comments

Comments

@dy
Copy link

dy commented Feb 7, 2016

Hi @mikolalysenko @hughsk!
There is another solution from here:

float shift_right (float v, float amt) { 
    v = floor(v) + 0.5; 
    return floor(v / exp2(amt)); 
}
float shift_left (float v, float amt) { 
    return floor(v * exp2(amt) + 0.5); 
}
float mask_last (float v, float bits) { 
    return mod(v, shift_left(1.0, bits)); 
}
float extract_bits (float num, float from, float to) { 
    from = floor(from + 0.5); to = floor(to + 0.5); 
    return mask_last(shift_right(num, from), to - from); 
}
vec4 encode_float (float val) { 
    if (val == 0.0) return vec4(0, 0, 0, 0); 
    float sign = val > 0.0 ? 0.0 : 1.0; 
    val = abs(val); 
    float exponent = floor(log2(val)); 
    float biased_exponent = exponent + 127.0; 
    float fraction = ((val / exp2(exponent)) - 1.0) * 8388608.0; 
    float t = biased_exponent / 2.0; 
    float last_bit_of_biased_exponent = fract(t) * 2.0; 
    float remaining_bits_of_biased_exponent = floor(t); 
    float byte4 = extract_bits(fraction, 0.0, 8.0) / 255.0; 
    float byte3 = extract_bits(fraction, 8.0, 16.0) / 255.0; 
    float byte2 = (last_bit_of_biased_exponent * 128.0 + extract_bits(fraction, 16.0, 23.0)) / 255.0; 
    float byte1 = (sign * 128.0 + remaining_bits_of_biased_exponent) / 255.0; 
    return vec4(byte4, byte3, byte2, byte1); 
}

The benefit is instant conversion of result to Float32Array:

var result = new Uint8Array(w * 4);
gl.readPixels(0, 0, w, 1, gl.RGBA, gl.UNSIGNED_BYTE, result);
result = new Float32Array(result.buffer); //← this guy is in theory very fast, instead of converting per-element

Just wanted to know your thoughts on that, because there are gl-texture2d-read-float and others depending on that.

@dy
Copy link
Author

dy commented Feb 11, 2016

Tiny benchmark has shown that there is no difference.
I guess it would be easier for a user to get float32array in return, if uint8array is passed as an argument:

var floatArray = unpackFloat(buffer);

@mikolalysenko what do you think?

@mikolalysenko
Copy link
Owner

This module also allows for instant conversion to a float32array. Look at how the decoding works: https://github.com/mikolalysenko/glsl-read-float/blob/master/index.js#L1-L12

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants