PDA

View Full Version : pack more than 4 components into RGBA 32 texture in vertex shader



DarioCiao!
01-17-2015, 05:44 AM
How can I pack more than 4 components into a RGBA (128 bits total, floating point) texture?

My GPU only support RGBA32 texture in vertex texture fetch, so I'm forced to use that pixel format

I need to pack ~8 bit and ~16 bits values so that I can access them in vertex shader after a texture fetch. It is ok for me to lose few bits of precision here and there, but I need to know how much I lose and where,

a dummy implementation would be (unpack RGB values from R channel of the texture), but I'm not aware of possible issues hided by GL abstraction (for example does the floating point conforms IEEE and so has 23 bits of mantissa?):





//unpacking
vec3 grb = vec3( floor(R/65536.0f), floor(R/256.0f), mod(R,256.0f) ); //green has 7 bits precision here. Additional precision by eventual leading zeros.

//packing
float Rpacked = floor(256.0f*b) + floor(65536.0f*r) + floor(8388608.0f*g);



My above implementation is quite stupid (assuming it is correct, I'm not even sure it is correct), because it relies only on the mantissa (well If I'm lucky enough so that the final resulting number has some zeroes in last positions in the mantissa I gain some bit of precision but hoping for luck is not a efficient encoding), while I could still exploit the exponent to store some additional info.
Actually I have 32 bits to store just 23 bits of information.

malexander
01-18-2015, 08:10 AM
The simplest way is to use multiple texels, which you can do by allocating a larger texture by increasing its dimension by a factor of texels-per-value in one direction and then indexing the texture multiple times. Alternatively, you can also use a multisample texture with the #samples set to the number of texels that you need.

If you are targetting OpenGL4, you can use unpack GLSL instructions to extract two or four values from a single 32b uint. The values are stored in either 8b fixed or 16b fixed format. If you can't use RGBA-uint32 as a texture format, you can use floatBitsToUint() first on the RGBA_32F components to convert the floats to uints.

Alfonse Reinheart
01-18-2015, 08:26 AM
My GPU only support RGBA32 texture in vertex texture fetch

I'm guessing you mean GL_RGBA8. Remember: the number represents the number of bits per component, not per pixel. I highly doubt that any graphics card who's vertex shaders can access 32-bit per component normalized integer textures is incapable of using GL_RGBA32UI in the VS.

mbentrup
01-19-2015, 02:04 AM
How can I pack more than 4 components into a RGBA (128 bits total, floating point) texture?

My GPU only support RGBA32 texture in vertex texture fetch, so I'm forced to use that pixel format

I need to pack ~8 bit and ~16 bits values so that I can access them in vertex shader after a texture fetch. It is ok for me to lose few bits of precision here and there, but I need to know how much I lose and where,

a dummy implementation would be (unpack RGB values from R channel of the texture), but I'm not aware of possible issues hided by GL abstraction (for example does the floating point conforms IEEE and so has 23 bits of mantissa?):





//unpacking
vec3 grb = vec3( floor(R/65536.0f), floor(R/256.0f), mod(R,256.0f) ); //green has 7 bits precision here. Additional precision by eventual leading zeros.

//packing
float Rpacked = floor(256.0f*b) + floor(65536.0f*r) + floor(8388608.0f*g);



My above implementation is quite stupid (assuming it is correct, I'm not even sure it is correct), because it relies only on the mantissa (well If I'm lucky enough so that the final resulting number has some zeroes in last positions in the mantissa I gain some bit of precision but hoping for luck is not a efficient encoding), while I could still exploit the exponent to store some additional info.
Actually I have 32 bits to store just 23 bits of information.

On old GPUs the FP implementation is not always IEEE compliant, but as far as i know that non-compliance is mostly in areas like NaNs and denormal number handling. You can assume that the floats have a 23 bit mantissa on every existing desktop hardware. Note that you can safely store 24 bits of data in the 23 bit mantissa, as the most significant one bit is not stored in the mantissa.