How do I convert a vec4 rgba value to a float?

后端 未结 5 1746
遇见更好的自我
遇见更好的自我 2020-12-03 15:29

I packed some float data in a texture as an unsigned_byte, my only option in webgl. Now I would like unpack it in the vertex shader. When I sample a pixel I get a vec4 whi

5条回答
  •  死守一世寂寞
    2020-12-03 16:12

    I tried Arjans solution, but it returned invalid values for 0, 1, 2, 4. There was a bug with the packing of the exponent, which i changed so the exp takes one 8bit float and the sign is packed with the mantissa:

    //unpack a 32bit float from 4 8bit, [0;1] clamped floats
    float unpackFloat4( vec4 _packed)
    {
        vec4 rgba = 255.0 * _packed;
        float sign =  step(-128.0, -rgba[1]) * 2.0 - 1.0;
        float exponent = rgba[0] - 127.0;    
        if (abs(exponent + 127.0) < 0.001)
            return 0.0;           
        float mantissa =  mod(rgba[1], 128.0) * 65536.0 + rgba[2] * 256.0 + rgba[3] + (0x800000);
        return sign *  exp2(exponent-23.0) * mantissa ;     
    
    
    }
    
    //pack a 32bit float into 4 8bit, [0;1] clamped floats
    vec4 packFloat(float f) 
    {
        float F = abs(f); 
        if(F == 0.0)
        {
            return  vec4(0,0,0,0);
        }
        float Sign =  step(0.0, -f);
        float Exponent = floor( log2(F)); 
    
        float Mantissa = F/ exp2(Exponent); 
        //std::cout << "  sign: " << Sign << ", exponent: " << Exponent << ", mantissa: " << Mantissa << std::endl;
        //denormalized values if all exponent bits are zero
        if(Mantissa < 1.0)
            Exponent -= 1;      
    
        Exponent +=  127;
    
        vec4 rgba;
        rgba[0] = Exponent;
        rgba[1] = 128.0 * Sign +  mod(floor(Mantissa * float(128.0)),128.0);
        rgba[2] = floor( mod(floor(Mantissa* exp2(float(23.0 - 8.0))), exp2(8.0)));
        rgba[3] = floor( exp2(23.0)* mod(Mantissa, exp2(-15.0)));
        return (1 / 255.0) * rgba;
    }
    

提交回复
热议问题