Encoding floats to RGBA - the final?
The saga continues! In short, I need to pack a floating point number in [0..1) range into several channels of 8 bit/channel render texture. My previous approach is not ideal.
Turns out some folks have figured out an approach that finally seems to work.
Here it is for my own reference:
-
Suggestion right there on my previous blog post comments
-
Repost gamerendering blog
-
Repost on gamedev.net forums again.
So here’s the proper way:
inline float4 EncodeFloatRGBA( float v ) {
float4 enc = float4(1.0, 255.0, 65025.0, 16581375.0) * v;
enc = frac(enc);
enc -= enc.yzww * float4(1.0/255.0,1.0/255.0,1.0/255.0,0.0);
return enc;
}
inline float DecodeFloatRGBA( float4 rgba ) {
return dot( rgba, float4(1.0, 1/255.0, 1/65025.0, 1/16581375.0) );
}
That is, the difference from the previous approach is that the “magic” (read: hardware dependent) bias is replaced with subtracting next component’s encoded value from the previous component’s encoded value.