Decode rgb value for one float without bit shift in glsl

I am currently busy with deferred shading in webgl, and I need to decode 3 integer values ​​(in the range [0..256] = 256 ^ 3) to one 32-bit float and encode it later. because it is for WebGL, it needs to be done without bitwise operations. accuracy is not important to me (but can be achieved, I think).

this is what I have, but I think it is wrong due to the accuracy 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(float 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..

+6
source share
3 answers

I know this is an old question, but I had the same problem and I will post a solution if someone needs it in the 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 normalize it! return color / 255.0; } 

As long as the float packaged by packColor is not in the range [0, 1], but in the range [0, 16777215], you should not have any problems with accuracy. But if you normalize the float in the range [0,1], you will have problems with accuracy!

Note that you also cannot store alpha (this way), since highp float is 24 bits long and not 32 bits as commonly used. In the vertex shader, you can use this code without problems (the default accuracy is highp), but in the fragment shader you have to be sure that you use only high precision!

+18
source

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); } 
+2
source

@Makers_F: Thanks for the GLSL code of the unpackColor function, but it seems that the 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 normalize it! return color / 256.0; } 
0
source

Source: https://habr.com/ru/post/894003/


All Articles