Writing HDR render targets to disk
-
- Ogre Magi
- Posts: 1137
- Joined: Mon May 07, 2007 3:43 am
- Location: Ossining, New York
- x 13
Writing HDR render targets to disk
I've tried writing to disk a FLOAT16_RGB buffer (for debug and baking purposes) using tiff, bmp, jpg, png, and tga, all of them resulted in corrupted images. Of these only tiff I think can even support more than an 8 bit range, but the others ought to do something sensible like clip to 1.
What's the right file format to use anyway?
Has anyone ever got this to work? Would using some other buffer format be a good idea (only other one I've tried so far is R8G8B8 which does work of course).
Is there any flag to use when creating the texture that makes this work better?
thanks
What's the right file format to use anyway?
Has anyone ever got this to work? Would using some other buffer format be a good idea (only other one I've tried so far is R8G8B8 which does work of course).
Is there any flag to use when creating the texture that makes this work better?
thanks
-
- Ogre Magi
- Posts: 1137
- Joined: Mon May 07, 2007 3:43 am
- Location: Ossining, New York
- x 13
Re: Writing HDR render targets to disk
Interesting discoveryt: If I render to a SHORT_RGB texture then I can export a tiff (which ends up in 16 bit per channel mode). This would be fine, except for some reason rendering to short takes a very long time. I suspect it's actually rendering to FLOAT32 and converting to SHORT on the CPU.
All of this is on Linux with a NVIDIA 80 series card (Quadro FX 3700M).
All of this is on Linux with a NVIDIA 80 series card (Quadro FX 3700M).
-
- Ogre Magi
- Posts: 1137
- Joined: Mon May 07, 2007 3:43 am
- Location: Ossining, New York
- x 13
Re: Writing HDR render targets to disk
I ended up rendering to a FLOAT32 texture, copying it to a FLOAT32 Ogre::Image, and then manually converting to an integer 16 bit per channel Ogre::Image (doing gamma encoding, scaling, and some other stuff on the way), then finally outputting to tiff, which seems to work OK.
-
- OGRE Expert User
- Posts: 1920
- Joined: Sun Feb 19, 2012 9:24 pm
- Location: Russia
- x 201
Re: Writing HDR render targets to disk
Interesting, but why did you expect any of those formats to support FLOAT16_RGB at all?
-
- Ogre Magi
- Posts: 1137
- Joined: Mon May 07, 2007 3:43 am
- Location: Ossining, New York
- x 13
Re: Writing HDR render targets to disk
It ought to convert them, or at least throw an error rather than create a corrupted file.
-
- Ogre Magi
- Posts: 1137
- Joined: Mon May 07, 2007 3:43 am
- Location: Ossining, New York
- x 13
Re: Writing HDR render targets to disk
I had no idea how to handle FLOAT16 data on the CPU though, presumably you have to do some bit arithmetic to convert it into a float first.
-
- OGRE Moderator
- Posts: 7157
- Joined: Sun Jan 25, 2004 7:35 am
- Location: Brisbane, Australia
- x 535
Re: Writing HDR render targets to disk
PNG can handle up to 16 bit per channel (and 4 channels). But no floating point formats.
JPG is rgb24 only (although internally it's really YCbCr).
TIFF can handle up to 16 bit per channel as well. Still no floats that I know of (but there's a heap of modes and extensions and stuff in TIFF).
BMP generally sucks.
OpenEXR (ogre can load them, not sure about saving) supports unlimited channels, each channel being either float16, float32 or unsigned int. You can name each channel as well, and it has both lossy and lossless compression.
DDS can handle pretty much any image format that the gpu can (a lot of people get DXT and DDS confused. DXT is just a tiny fraction of DDS's available formats). It supports 1, 2 or 4 channels of float16 or float32, as well as other interesting ones such as A2R10G10B10. But again, I'm not sure if ogre can save them.
(OpenEXR comes with source code for handling float16 on the cpu).
JPG is rgb24 only (although internally it's really YCbCr).
TIFF can handle up to 16 bit per channel as well. Still no floats that I know of (but there's a heap of modes and extensions and stuff in TIFF).
BMP generally sucks.

OpenEXR (ogre can load them, not sure about saving) supports unlimited channels, each channel being either float16, float32 or unsigned int. You can name each channel as well, and it has both lossy and lossless compression.
DDS can handle pretty much any image format that the gpu can (a lot of people get DXT and DDS confused. DXT is just a tiny fraction of DDS's available formats). It supports 1, 2 or 4 channels of float16 or float32, as well as other interesting ones such as A2R10G10B10. But again, I'm not sure if ogre can save them.
(OpenEXR comes with source code for handling float16 on the cpu).
-
- Ogre Magi
- Posts: 1137
- Joined: Mon May 07, 2007 3:43 am
- Location: Ossining, New York
- x 13
Re: Writing HDR render targets to disk
Ogre only uses freeimage to save I think so no dds output. DDSCodec doesn't support writes I think. Maybe with devil instead of freeimage it could be done. Otherwise, the dds support is a bit weak generally, every time I've tried to use a volume or cube map, I've gotten a crash. It's on my list of things to look into.
DDS is also quite weak on Linux generally -- the gimp plugin is buggy and lacks features like supporting normal maps in mipmap generation. It's also a bit clunky when it comes to volume textures and mipmaps since it uses layers for both. I wish there was a fully featured netpbm backend for dds, that would be sweet. You could work with your texture in gimp, export it as a tiff, then convert to DDS on the commandline, doing whatever DXT compression or mipmap generation you feel like. Netpbm output for Ogre texture buffers might be sane as well.
If all this was addressed I think dds would be the most appropriate format by far. The ability to deal with FLOAT16 would save having to do gamma encoding for example.
OpenEXR is going to be heavily compressed right? Not sure how much of a big deal this is given CPU vs disk IO performance these days.
Another big problem is lack of decent tools for painting / viewing HDR textures. In particular, viewing dds files in Linux is a big pain even for LDR textures.
Useful to know that png supports 16 bits per channel, probably I can export to that from Ogre if I populate a PF_SHORT_RGBA Ogre::Image first. Definitely outputting FLOAT16 to it produced garbage.
DDS is also quite weak on Linux generally -- the gimp plugin is buggy and lacks features like supporting normal maps in mipmap generation. It's also a bit clunky when it comes to volume textures and mipmaps since it uses layers for both. I wish there was a fully featured netpbm backend for dds, that would be sweet. You could work with your texture in gimp, export it as a tiff, then convert to DDS on the commandline, doing whatever DXT compression or mipmap generation you feel like. Netpbm output for Ogre texture buffers might be sane as well.
If all this was addressed I think dds would be the most appropriate format by far. The ability to deal with FLOAT16 would save having to do gamma encoding for example.
OpenEXR is going to be heavily compressed right? Not sure how much of a big deal this is given CPU vs disk IO performance these days.
Another big problem is lack of decent tools for painting / viewing HDR textures. In particular, viewing dds files in Linux is a big pain even for LDR textures.
Useful to know that png supports 16 bits per channel, probably I can export to that from Ogre if I populate a PF_SHORT_RGBA Ogre::Image first. Definitely outputting FLOAT16 to it produced garbage.
-
- OGRE Moderator
- Posts: 7157
- Joined: Sun Jan 25, 2004 7:35 am
- Location: Brisbane, Australia
- x 535
Re: Writing HDR render targets to disk
OpenEXR has 8 different compression options: none, run length encoding, per line zip, per 16 lines zip, piz (combination of wavelet and huffman), pxr24 (Pixar's format), b44 and b44a.OpenEXR is going to be heavily compressed right? Not sure how much of a big deal this is given CPU vs disk IO performance these days.
I just took a look at ogre's dds code. It does support saving to a file, but only in formats PF_A8R8G8B8, PF_X8R8G8B8, PF_R8G8B8 and PF_FLOAT32_R.Ogre only uses freeimage to save I think so no dds output. DDSCodec doesn't support writes I think.
Which is a shame. I wonder if it's just linux developers being biased against something made by microsoft and called Direct Draw Surface without really looking at what it can do? It's actually a damn good format for games and the DXT modes it contains are opengl compatible. Plus it handles image arrays, manual mipmaps, voxels, cube maps, etc. It's also a very simplistic format code wise, depending on what features you want to use. Writing to a dds requires not much code, just write a magic number, a small header structure then a dump of the raw texture data.DDS is also quite weak on Linux generally
Cinepaint used to be good for that. It supports openexr, 16bit per channel and floating point hdr formats. It's a fork of Gimp designed for the movie industry (and used in a heap of big movies). But I stopped following it years ago, they were crap at supporting windows and the rewrite for version 1.0 was taking forever. Apparently there was a release 9 months ago, maybe it's usable.Another big problem is lack of decent tools for painting / viewing HDR textures.
http://www.cinepaint.org/
-
- Ogre Magi
- Posts: 1137
- Joined: Mon May 07, 2007 3:43 am
- Location: Ossining, New York
- x 13
Re: Writing HDR render targets to disk
I don't think there's any real bias. Otherwise bmp wouldn't be supportedI wonder if it's just linux developers being biased against something made by microsoft and called Direct Draw Surface without really looking at what it can do? It's actually a damn good format for games and the DXT modes it contains are opengl compatible. Plus it handles image arrays, manual mipmaps, voxels, cube maps, etc. It's also a very simplistic format code wise, depending on what features you want to use. Writing to a dds requires not much code, just write a magic number, a small header structure then a dump of the raw texture data.

There are strong technical reasons for dds so I think it's just lack of momentum in realtime graphics on Linux. I have been threatening to do a netpbm dds backend myself for years but it's possible to struggle on without it so I've always pushed it to the side in favour of more direct work on graphics. I've also been using wine to run windows viewers with barely sufficient success.
One problem I think is that dds really needs a special viewer, because of all the mipmaps, cubes, volumes, and the fact people want to preview normal maps using a lighting equation. So e.g. adding support to geeqie/gqview would not cut it.
-
- OGRE Team Member
- Posts: 5511
- Joined: Sat Jul 21, 2007 4:55 pm
- Location: Buenos Aires, Argentina
- x 1379
Re: Writing HDR render targets to disk
Here's a library that will do the Half float conversion for you (you only need the .c & .h files in it, two in total)
Like Kojak said, only OpenEXR supports half16 formats, PNG can do 64-bit images (but integer only!) and TIFF supports floats (32-bit) but not every program may read it (it's relatively new). You're best converting it to 32-bit float and saving it in either EXR or TIFF (or use colour).
Like Kojak said, only OpenEXR supports half16 formats, PNG can do 64-bit images (but integer only!) and TIFF supports floats (32-bit) but not every program may read it (it's relatively new). You're best converting it to 32-bit float and saving it in either EXR or TIFF (or use colour).
-
- OGRE Expert User
- Posts: 1920
- Joined: Sun Feb 19, 2012 9:24 pm
- Location: Russia
- x 201
Re: Writing HDR render targets to disk
Ogre::Bitwise already has conversion methods for float16's btw.