Encoding floats to RGBA, redux

Gleserg has interesting comments in my earlier post. So I thought I’d share what I am using right now, and try to throw some more complexities in :)

Here is what I am doing right now:

 inline float4 EncodeFloatRGBA( float v ) {
   return frac( float4(1.0, 255.0, 65025.0, 16581375.0) * v ) + 0.5/255.0;
 }
 inline float DecodeFloatRGBA( float4 rgba ) {
   return dot( rgba, float4(1.0, 1/255.0, 1/65025.0, 1/16581375.0) );
 }

And this seems to work fine almost everywhere (see below). Why am I doing this - good question, I don’t have a hard theory on which bits go where and so on. I think I saw someone on gamedev.net forums saying that in hardware 0 == 0.0 and 255 == 1.0, and that truncation is actually done on the values (not rounding). So that would mean you multiply by 255 and add a half of a bit.

Now, the trick: the above does not quite work on Radeons (at least the X1600 that I’m mostly developing on while I’m on a Mac). Instead of adding 0.5/255.0, you have to subtract 0.55/255.0 - and that value is still not perfect, but that’s the best I could come up with by plowing through various combinations. I have no idea why this must be performed (24 bit internal precision? or does it round up? something else?). On GeForces and even Intel’s shader-capable hardware, the expected +0.5/255.0 value works.

…anyone up to figuring out the mathematical proof on why encoding/decoding this way actually works? :) And yes, the last component (the one that uses 16581375) is pretty much meaningless.


My battery is better than yours

My battery!

That’s a pretty decent battery time for a laptop, I must say! Too bad it did not actually last 300 hours…


OpenGL pbuffers suck!

Aaargh! Well, the blog title is about as much as I wanted to say on this topic.

…this is just me venting out, during the process of chasing a video memory leak for 4 days already. It involves p-buffers, depth textures, shared OpenGL contexts and other delicious things. Still didn’t find the cause, but I’m getting close.

Pbuffer my a**.



Now that's what I call a good API (stb_image)

The other day at work I needed a command line tool to compare some images (whether they mostly match, used in unit/functional tests). For unknown reason I could not get ImageMagick’s compare to work like I wanted, so I just wrote my own.

I used stb_image library from Sean Barrett - and it just rocks! Here’s the code to load a PNG image from file:

 int width, height, bpp;
 unsigned char* rgb = stbi_load( "myimage.png", &width, &height, &bpp, 3 );
 // rgb is now three bytes per pixel, width*height size. Or NULL if load failed.
 // Do something with it...
 stbi_image_free( rgb );

That’s it! Basically a single line to load the image (and of course the library has similar functions to load from a block of memory, etc.). And the whole “library” is a single file - just add to your project and there it is. In comparison, loading a PNG file using de-facto libpng takes more than 100 lines of code (and some time to read the docs).

Small is beautiful.

…and the way we do graphics related unit/functional/compatibility testing deserves a separate article. Sometime in the future!