32-Bit/Texel HDR 3-component Color formats

Hello,

are there any 32-Bit (per Texel) Texture Formats for storing HDR color that are well suited to be used as both: FBO Attachment and Samplers? I’m not too worried about backwards compatibilty (DirectX 10 hardware can be expected), but I’d like to know if someone found a better solution than using 64-Bit Textures.

The answer appears to be so straightforward that I cannot get rid of the feeling to overlook something. I’ve made it a spoiler so you may chose not being influenced by it when looking for a solution.

<div class=“ubbcode-block”><div class=“ubbcode-header”>Warning, Spoiler: <input type=“button” class=“form-button” value=“Show” onclick=“if (this.parentNode.parentNode.getElementsByTagName(‘div’)[1].getElementsByTagName(‘div’)[0].style.display != ‘’) { this.parentNode.parentNode.getElementsByTagName(‘div’)[1].getElementsByTagName(‘div’)[0].style.display = ‘’;this.innerText = ‘’; this.value = ‘Hide’; } else { this.parentNode.parentNode.getElementsByTagName(‘div’)[1].getElementsByTagName(‘div’)[0].style.display = ‘none’; this.innerText = ‘’; this.value = ‘Show’; }” />]<div style=“display: none;”>
R11f G11f B10f - This appears to be the best fit.

RGB9e5 - Can only be used as Sampler, according to spec. :frowning: Any insider info whether this changes at some point?

RGBe8 - internally using RGBA8. Not native to GL, but you could probably treat the RGB values as mantissa and use the alpha channel as a shared exponent and pack/unpack with GLSL when writing/reading. This would be very fragile and is probably not a good idea.

Some other possibilities considered but abandoned as “worse than the ones above”

RGBA8 - treating Alpha as Intensity as proposed in http://www.guerrilla-games.com/publications/dr_kz2_rsx_dev07.pdf

RGB10A2 - internally stored as RGBA8 according to http://http.download.nvidia.com/developer/OpenGL_Texture_Formats/nv_ogl_texture_formats.pdf
[/QUOTE]</div>

You can use GL_RGB32F_ARB internal texture format for 32 bits floating point textures.

Sorry, edited the initial post to clarify that I’m looking for 32 Bits/Texel rather than 32 Bits/Component formats.

According to the second linked document that format is 128 Bits/Texel in hardware. Due to MRT rules all attachments must have the same dimension/Bitcount, so rather squeeze the data into 32 Bits. That already results in a ~5MB Texture, 128 Bits would be ~20MB for a single Texture.

there are no great formats with those parameters, there is something called RGBE but it’s really just a hack that works well for the gray wastelands in KZ2, but probably not if you like, you know, colors.
R11f G11f B10f and all of those have other problems, like no real dynamic range, at least with any quality.
GL_RGB16F_ARB is probably your best bet with the best hardware support.

Though it depends, if you can spare a few extra megabytes for a renderbuffer, or if you rather limit quality slightly.

I beg to differ. Of course the color precision is lower on the high level exponents than for a full fledged RGB16F, but the color saturation is still there. At least as good as RGB8.

implementation :
http://www.smetz.fr/wp-content/uploads/2007/01/hdr_opengl.pdf
And all these probes are in RGBE file format :
http://www.debevec.org/Probes/

It depends on what your doing with it, Warshade mentioned MRT and using it for read and write, the most common use for that is probably deferred rendering of some sort, which means that channel independent precision and sign bits are important, as your not rendering something that is to be seen subjectively, but is used for computation.

Also what i meant with RGBE is that let’s say you have the red channel as fully “lit” close to the highest value, then you have blue and green close to the lowest possible values.
Then either you loose the brightness on the red, or you loose both blue and green depending on the exponent, that is not good.
I would always choose 16f or 32f on the main render buffer, especially if i have to do post processing.

let’s say you have the red channel as fully “lit” close to the highest value, then you have blue and green close to the lowest possible values.
Then either you loose the brightness on the red, or you loose both blue and green depending on the exponent
… and almost nothing of value was lost.

I mean, color information don’t really need more than 16 million different colors, the eye can hardly separate finer colors. Brightness value does need it, most compressed image formats (jpeg, RGBE, LogLuv) have higher compression ratio on the color information than on the luminance information.

This has been done with one of the RGBE Debevec’s HDR images :
http://www.mpi-inf.mpg.de/resources/hdrvideo/supplemental/bloom.png

Do you really see problems with the colors ?

Sure if you can afford it, full floats have higher quality. But if size is constrained, give RGBE a try :slight_smile:

Please, if there is an RGBe8 Extension: point me towards it! Kinda put my hopes on RGB9e5, but since it cannot be attached to a FBO it’s useless.

The reason why I haven’t investigated the RGBe8 approach - described in the spoiler - further is blending. It looks as if the only way to accomplish that would be using 2x RGBe8 Textures. Bind Tex2 as Sampler, attach Tex1 to FBO, manually add lighting accumulation from Tex2 and current light to Tex1. Detach Tex1 from FBO, Unbind Tex2 from Sampler. Attach Tex2 to FBO, bind Tex1 as Sampler. Repeat. This will most likely perform so bad that it’s not even worth further consideration, and has the drawback that it requires 2x 32Bit/Texel Textures. So might aswell use 1x 64Bits/Texel.

The idea I really liked best would be using RGB10A2 integer format. The range needed for each component would be sufficient in the [0…2] range, which could be achieved by simple multiplication. Blending should work nicely. 2 unused bits isn’t optimal, but beats 8 unused bits.
However only Ati uses 10 Bits/Component for this format, Nvidia only 8. Yeah, this must be a punch in the stomach for Nvidia fanboys - Ati is not the scapegoat for once :wink:

Thought it would be a good idea to write down my conclusion, since noone seems to have any good advice: Simply support both RG11fB10f and RGB9e5. The latter doesn’t work yet, but it might do in the future.