The effect of quantization in gamma space and linear space

I mentioned already (here and here) that one problem with gamma correct rendering is how we lose prevision for small values, and may run out of it if we didn’t have enough of it. I wrote a quick shader to demonstrate this problem and see how severe it is depending on the number of bits.

Thanks to BeautyPi‘s fantastic tool, ShaderToy, I could put it on line. Here is the live demo with an absurdly low precision format (R5G6B5) so you cannot miss the banding; just press the play button. It displays colors with maximum and low precision, in linear space and gamma space. The lighter vertical line shows the 50% intensity position. You can see the shader and play with the values here.

Gamma correct and HDR rendering in a 32 bits buffer

Recently I am looking for the available options for doing gamma correct and/or HDR rendering in a 32 bits buffer. Gamma correct means you need higher precision for low values (this article by Benjamin Supnik demonstrates why). HDR means you may have values greater than 1, and since your range is getting wider, you want higher precision everywhere. The way to go recommended everywhere is to use 16 bits floats, like RGBA16, or even higher. But suppose you don’t want your buffer to get above 32 bits, what tools are available?

Note: the article has been reworked as I gathered more information. I thought organizing them was better than merely adding an update notice at the end.


My first thought was to use standard RGBA8, store the maximum of the RGB channels in the alpha channel, and store the RGB vector divided by that scale. A back of the envelope test later, I was forgetting about it, convinced it wouldn’t go very far: since values are limited to the [0, 1] range, it would require to define the maximum value meant when alpha is 1. More importantly, interpolation would give incorrect results.

Or so I thought. It seems doing this is known as RGBM (M for shared multiplier) and while indeed the interpolation gives incorrect results, this article argues they are barely noticeable, and the other advantages outweigh it (see RGBD here after for an other worth reading article).

There are also variations of this approach, as shown on this online Unity demo. Here is the code.


By searching on the web I first found this solution, consisting in storing the inverse of the scale in the alpha channel. Known as RGBD (D for shared divider), it doesn’t suffer from having to define a maximum value, and plotting the function seems to show an acceptable precision across the range. Unfortunately it doesn’t interpolate either.

This article gives a good comparison of RGBM and RGBD, and addresses the question of interpolation. Interestingly, it notes that while neither have correct interpolation, whether it may acceptable or not depends on the distribution of the colors.


Then you have the RGBE (E for shared exponent): RGB and an exponent. Here is a shader implementation using an RGBA8 buffer. But then again, because of the exponent being stored in the alpha channel, interpolation is going to be an issue.


Further searching, I stumbled upon the OpenGL EXT_texture_shared_exponent extension, which defines a GL_RGB9_E5 texture format with three 9 bits components for the color channels, and an additional 5 bits exponent shared by the channels. This sounded nice: 9 bits of precision is already twice as many shades, and the exponent gives precision everywhere, as long as the channels values have the same order of magnitude. Because it is a standard format, I assume interpolation is going to be a non issue. Unfortunately as can be read on the OpenGL wiki, while this is a required texture format, it is not required for renderbuffers. In other words: chances are it’s not going to be implemented.


Since we really want a wide range of light intensity, a different approach is to use a different color space. Several people mentioned LogLUV, which I hear gives good results, at the expense of a high instruction cost for both packing and unpacking. Here is a detailed explanation.


There is still the R11F_G11F_B10F format (DXGI_FORMAT_R11G11B10_FLOAT in DirectX) where R and G channels have a 6 bits mantissa and a 5 bits exponent, and B has a 5 bits mantissa and 5 bits exponent. Since floats have higher precision with low values, this seem very well suited to gamma correct rendering. And since this is a standard format, interpolation should be a non issue.


I haven’t tested in practice yet, but from these readings it seems to me the sensible solution would be to use a R11G11B10 float format when available. Otherwise (for example on mobile platforms) choose between RGBM and RGBD depending on the kind of image being rendered. Unless the format is standard, it seems interpolation is always going to be an issue, and the best you can do is mitigate by choosing the solution depending on your use case.

Did I miss something?


More and more material and news are being released about the next edition of SIGGRAPH, so here is a short summary.

Technical papers

The video teaser of the technical papers has been published. It looks like there will be some really cool stuff to see. As every year Ke-Sen Huang maintains a page with the list of papers.

Real Time Live!

The Real Time Live! program looks very nice too, and it is good to see at least two demoscene related works will be presented there (the community GLSL tool ShaderToy by Beautypi, and some experiment by Still with a LEAP Motion controller on their production, Square).


Not much to say, it looks great and I want to see most of them… The Advances in Real-Time Rendering in Games and Physically Based Shading in Theory and Practice courses are a must see as usual. The Recent Advances in Light-Transport Simulation: Theory & Practice and Ray Tracing is the Future and Ever Will Be courses sound promising too.

Our work to be shown at SIGGRAPH

Lastly, we had some awesome news yesterday, when we were told our last released demoscene production, F – Felix’s workshop, has been selected to be shown as part of the Real-Time Live! demoscene reel event.

Released last year at Revision and ranking 2nd in its category, Felix’s workshop is a 64k intro: a real-time animation fitting entirely (music, meshes, textures…) within a 64kB binary file meant to run on a consumer level PC with a vanilla Windows and up to date drivers.

I was also told Eddie Lee‘s work, Artifacts, was selected as well. His outstanding demo won at Tokyo Demo Fest earlier this year.

Tokyo City Symphony: a video mapping on a model of Tokyo

I was impressed by the quality of this work. The model looks very accurate, the soundtrack captures the sound environment one experiences in Tokyo, and the video mapping comes with some nice ideas.

The project seems to allow even more than is shown on the video, with some interactive mapping: see the Tokyo City Symphony website.

Two online color picking tools

Color Scheme Designer is a tool I have been for a while now, but more recently I discovered Color Sphere. Both are very helpful when it comes to choosing an harmonious set of colors. Color Scheme Designer gives much more control over colors repartition and has more export options, while Color Sphere has more rules and a simpler interface. Both allow to test the color set against various kinds of color blindness.