开发者

decode rgb value to single float without bit-shift in glsl

开发者 https://www.devze.com 2023-03-24 09:05 出处:网络
I\'m currently busy with deferred shading in webgl and i need to decode 3 integer value\'s (in the range [0..256] = 256^3)to a single 32 bit float and encode it later. because this is for WebGL it has

I'm currently busy with deferred shading in webgl and i need to decode 3 integer value's (in the range [0..256] = 256^3) to a single 32 bit float and encode it later. because this is for WebGL it has to be done without bitwise operations. precision is not important for me (But can be achieved i think).

this is what i have but i think this is wrong because of the precision of the texture where i store the encoded value.

float packColor(vec3 color) {   return (color.r + (color.g*256.) + (color.b*256.*256.)) / (256.*256.*256.); }

vec3 decodeColor(fl开发者_JAVA百科oat f) { 
float b = floor(f * 256.0);
float g = floor(f * 65536.0) - (b*256.);
float r = (floor(f * 16777216.0) - (b*65536.)) - (g*256.);
return vec3(r, g, b)/ 256.0;//vec3(r, g, b) / 256.0;  }

thanks..


I know this is an old question, but i had the same problem, and i'll post the solution in case someone needs it in future

float packColor(vec3 color) {
    return color.r + color.g * 256.0 + color.b * 256.0 * 256.0;
}

vec3 unpackColor(float f) {
    vec3 color;
    color.b = floor(f / 256.0 / 256.0);
    color.g = floor((f - color.b * 256.0 * 256.0) / 256.0);
    color.r = floor(f - color.b * 256.0 * 256.0 - color.g * 256.0);
    // now we have a vec3 with the 3 components in range [0..255]. Let's normalize it!
    return color / 255.0;
}

As long the float packed with packColor is not in the [0, 1] range but in the [0, 16777215] range, you shouldn't have any problem with precision. But if you normalize the float in the [0,1] range, you'll have precision problems!

Note that you can't store alpha too(in this way), since highp floats are 24-bit long, and not 32 as the ones normally used. In vertex shader you can use this code without problems(default precision is highp), but in the fragment shader you must be sure to only use high precision!


Like this?

function pack(color)  { return color.r + color.g * 256 + color.b * 256 * 256; }

function unpack(f)  {
    var b = Math.floor(f / (256 * 256));
    var g = Math.floor((f - b * 256 * 256) / 256);
    var r = Math.floor(f % 256);
    return vec3(r, g, b);
}


@Makers_F: Thanks for the GLSL code of unpackColor function, but it seems that blue and red components are reversed.

For me, the following code works like a charm:

vec3 unpackColor(float f) 
{
    vec3 color;

    color.r = floor(f / 256.0 / 256.0);
    color.g = floor((f - color.r * 256.0 * 256.0) / 256.0);
    color.b = floor(f - color.r * 256.0 * 256.0 - color.g * 256.0);

    // now we have a vec3 with the 3 components in range [0..256]. Let's normalize it!
    return color / 256.0;
}
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号