Terragen OpenEXR implementation

Started by PabloMack, September 18, 2014, 11:11:08 AM

Previous topic - Next topic

PabloMack

In the process of trying to use rendered images for lighting of live sets I came to the realization that I was on the road to problems using BMP "flat and shallow files". Most of the light in direct sunlight comes from a brilliant light source. Consequently, rendered images containing the disk of the sun saved to BMP or other limited LDRI file formats are going to saturate by clipping the light levels to white and, therefore, throw away most of the light needed to light the scene. I don't think that 16-bit light levels are going to solve my problem because integer data types are treated as though they were fractional numbers with the binary point just to the left of the highest order bit. Bright light sources will still saturate and be clipped to white.

I looked at the file saving options and saw OpenEXR as one of the formats supported by Terragen. Doing a bit of research I found the website where I can download a lot of information including source code and good documents describing the "standard". Reading the documents, though, brings me to the understanding that OpenEXR is not a simple format and can store multiple resolutions, use multiple different encoding methods in the same image file and even store multiple images.

So my first attempt was to download and compile source code for the simple image viewer. Immediately I ran into problems as not all of the needed files were part of the package. Now I am reading the technical documents and may try to understand the file format and write the file access code myself. All I need is code that will read the file. Preferably white values will have luminance values of 1 (or [1,1,1] as RGB) while normal image values will be fractional. Bright parts of the images that would clip to 1 should come through as numbers greater than 1 stored in a floating point format. Single-precision IEEE754 should be acceptable. What I would like to do is to get a general idea of the choices that PS made in the OpenEXR format options they decided to implement. It would seem to me that the only (or at least main) reason to support this format is to store HDRI images. Can someone give any insights into PS's implementation?

The next thing I plan to do is to start peeking into the OpenEXR files generated by TG.

Matt

#1
Hi,

Terragen 2 and Terragen 3 write EXRs with Zip compression and half float (16-bit) precision. There are three channels, which are the standard 'R', 'G' and 'B' channels. We make use of the OpenEXR libraries to do the main work of writing the file (with some custom code to drive the writer per scanline so that we make efficient use of memory while writing the file, but that's just an implementation detail).

The EXR header we use is the default constructor for the Header class in OpenEXR 1.7 (except for 'width' and 'height' of course), which I'm quoting here from ImfHeader.h:

Quote
class Header
{
  public:
   
    //----------------------------------------------------------------
    // Default constructor -- the display window and the data window
    // are both set to Box2i (V2i (0, 0), V2i (width-1, height-1).
    //----------------------------------------------------------------

    Header (int width = 64,
       int height = 64,
       float pixelAspectRatio = 1,
       const Imath::V2f &screenWindowCenter = Imath::V2f (0, 0),
       float screenWindowWidth = 1,
       LineOrder lineOrder = INCREASING_Y,
       Compression = ZIP_COMPRESSION);

    ...

Now, having said that, it's very likely that we'll make use of other options in future, such as full float (32-bit), alpha channel, and more. I wouldn't recommend treating Terragen EXRs as a static thing. I would recommend trying to get the OpenEXR libraries working in your code. When reading EXR files into Terragen, we use the OpenEXR libraries. If you do the same, your tool will be better prepared for any changes we make in future, and you'll also be better prepared to read EXRs from Lightwave or any other package you interface with in future.

Matt
Just because milk is white doesn't mean that clouds are made of milk.

PabloMack

#2
Quote from: Matt on September 18, 2014, 04:25:58 PMI wouldn't recommend treating Terragen EXRs as a static thing. I would recommend trying to get the OpenEXR libraries working in your code.

Fair enough. I was just starting to have fun until I discovered Zip compression. I'll go back to working with the libraries. Thanks for the extra information on your implementation.

PabloMack

#3
I downloaded the OpenEXR libraries and the file viewer program sources. I was trying to compile the FileReadingThread.cpp file and my compiler choked on the "namespace" construct. I wrote a detailed description and posted the problem on the OpenWatcom C++ news group a week or so ago and Marty said he would take a look at it. I haven't heard back from him yet. What I have gathered from reading the docs is that the namespace construct was put in there so that both 2.2 and 1.7 methods could coexist and be used in the same libraries without having to change any of the names. If the compiler problem isn't ironed out my only recourse (short of buying another compiler) may be to manually cut out the 1.7 elements from the libraries. My hopes of getting a new version of the compiler soon are not very high. Though it is under active development, the last release was in 2010! This is probably because they are in the midst of adding support for 64-bit address space as well as ARM7 as a target.

jo

Hi,

Have you thought about trying gcc? Probably a hassle to change over but at least it's a free up-to-date compiler and if you're running into problems then it could be worth making the change. We use gcc on Linux and used to use it on the Mac until fairly recently. I've never used it on Windows myself but I guess you'd do it using MinGW.

If you're looking for a free IDE you might check out Code::Blocks:

http://www.codeblocks.org

I use it for the Linux version of TG, with gcc. It's not super awesome but it's ok.

Regards,

Jo

PabloMack

Quote from: jo on October 08, 2014, 02:41:42 AMHave you thought about trying gcc?...
Hi Jo,

Over the years as an embedded electronics and programming
veteran, I have made three or four attempts at using the GCC
too-chain. I could never get the warm fuzzies as I do a lot of
assembly to supplement my C code for such things as catching
and handling overflows and whatnot. As you probably know,
the GCC assemblers have their own peculiar syntax and do not
conform to the language syntax's of the assemblers put out by
the architecture originators. Coupled with a shortage of out-of-
the-box integrated modern features, I just never have used it
much. A recent idea was to use it as a back-end for the cross
compiler I have been writing for a parallel programming language
of my own creation. I may yet look into the GCC direction again
some day.

Thanks for the suggestion.

Paul