POV-Ray : Newsgroups : povray.beta-test : Gamma in POV-Ray 3.6 vs. 3.7 : Re: Gamma in POV-Ray 3.6 vs. 3.7 Server Time
5 Oct 2024 00:39:39 EDT (-0400)
  Re: Gamma in POV-Ray 3.6 vs. 3.7  
From: Ive
Date: 12 Sep 2009 07:30:18
Message: <4aab864a@news.povray.org>
clipka wrote:
> I've spent some time on digging through the gamma handling as currently 
> done by POV-Ray 3.7, as well as examining how exactly POV-Ray 3.6 
> handles things.
> 
> This is what I found how 3.6 apparently does behave, and how I think 
> POV-Ray theoretically should behave.
> 
> 
> Depending on whether assumed_gamma is specified or not, two operational 
> modes can be distinguished in 3.6, which I will call "Assumed Gamma 
> Mode" and "Screwed-Up Mode".
> 
> 
> (A) "Assumed Gamma Mode":
> 
> If an assumed_gamma is specified, POV-Ray 3.6 presumes that all "raw" 
> colors - whether literal color values in the SDL file, encoded color 
> data in input files or the encoded output image - are gamma 
> pre-corrected for the specified gamma value, unless noted otherwise. It 
> further assumes that computations should be performed on these raw color 
> values, without converting them to linear values first.
> 
> Therefore, gamma correction is only performed on the preview display, 
> taking into account both the assumed_gamma as well as the Display_Gamma 
> setting.
> 
> PNG files with a gAMA chunk make an exception:
> 
> PNG output data undergoes the very same gamma transformation as the 
> preview output, i.e. the encoded data will be pre-corrected for the 
> specified Display_Gamma. In addition, a gAMA chunk is written matching 
> the Display_Gamma, so that the image displays as previewed (provided 
> Display_Gamma was set properly) on any computer, provided the viewing 
> software respects the gAMA chunk and knows about its own display gamma.
> 
> For PNG input files coming with a gAMA chunk, the encoding gamma 
> information stored in the chunk is honored, and full gamma correction is 
> performed to account for (a) the encoding gamma as per the gAMA chunk, 
> and (b) the assumed_gamma.
> 
> (Input files used in situations where the image is obviously(!) used as 
> a mere data container, such as with height fields, are exempt from this 
> rule: They never undergo gamma adjustment, even if they are stored as 
> PNG files with a gAMA chunk.)
> 
> 
> (B) "Screwed-Up Mode":
> 
> If no assumed_gamma is specified, POV-Ray 3.6 presumes that all "raw" 
> colors - whether literal color values in the SDL file, encoded color 
> data in input files or the encoded output image - are gamma 
> pre-corrected to match whatever Display_Gamma happens to be set to.
> 
> Therefore, no gamma correction is performed whatsoever... in general.
> 
> Indeed, no gamma correction or -encoding is performed on PNG output 
> files; however, a gAMA chunk is written matching the Display_Gamma, so 
> that the image again displays as previewed.
> 
> As for PNG input files coming with a gAMA chunk, these *are* 
> gamma-adjusted, for rather obscure reasons, in a rather obscure way: 
> Aside from taking into account both the encoding gamma as per the gAMA 
> chunk, as well as the Display_Gamma, an additional constant gamma of 2.2 
> seems to have been mixed in.
> 
> (Again, input files obviously used as a mere data container are exempt 
> from this gamma adjustment.)
> 
> 
> Neither mode is really any good, for the following reasons:
> 
> (A) with a gamma of 2.2 (or anything other than 1.0, for that matter) 
> will produce physically incorrect results, because the computations are 
> designed to work on linear values, not gamma pre-corrected data 
> (although the latter is how they had been typically used for decades, 
> but that's a different story).
> 
> (A) with a gamma of 1.0 (or anything other than 2.2, for that matter) is 
> unable to properly handle any non-PNG input images that use gamma 
> pre-correction (which is virtually all material out in the wild). In 
> addition, it will require image post-processing (format conversion or 
> gamma adjustment) if any format other than PNG, HDR or OpenEXR is 
> required with gamma pre-correction applied; output will also be 
> percieved to exhibit a loss of precision, due to using linear instead of 
> gamma encoding, unless a high color depth or a high dynamic range file 
> format is used for output. (The current implementation also suffers from 
> PNG input quality being degraded due to the gamma transformation.)
> 
> (B) suffers from the same problems as (A), except that it perfectly 
> screws up on PNG input files.
> 
> 
> This is exactly the reason why 3.7 is moving towards yet another gamma 
> handling mode, which I'll call "Proper Gamma Mode":
> 
> 
> (C) "Proper Gamma Mode":
> 
> The proper way of handling gamma is to perform all computations on 
> proper linear color values, while allowing for both input and output 
> files to use gamma encoding or pre-correction.
> 
> Therefore, gamma adjustment must be performed (or at least considered) 
> on *all* output (both files and preview), as well as any input files 
> (unless obviously used as a mere data container). The same should go for 
> colors explicitly specified in the scene file.
> 
> For output, this gamma correction is governed by Display_Gamma, 
> specifying the gamma pre-correction to be used for preview, as well as 
> File_Gamma, governing the gamma encoding or pre-correction to be used.
> 
> Furthermore, for file formats defining a standard way to handle gamma, 
> the standard should be adhered to, ignoring File_Gamma if necessary. 
> This allows for one and the same File_Gamma setting to give good results 
>  with all output file formats, whether they are typically expected to be 
> gamma pre-corrected due to lack of explicit specification (e.g. BMP or 
> JPEG), explicitly specified to use a variable encoding gamma (e.g. PNG 
> with gAMA chunk), or explicitly specified to use linear encoding (e.g. 
> OpenEXR). This allows a casual user to define a sane File_Gamma in his 
> global povray.ini, and not worry about the setting regardless of output 
> file format.
> 
> For input files, there is no proper handling implemented yet. However, I 
> propose the following solution:
> 
> - A global SDL setting "file_gamma", to specify the gamma pre-correction 
> to assume for input files.
> 
> - File format specifications take precedence over the global 
> "file_gamma" setting, e.g. PNG files with a gAMA chunk are 
> gamma-adjusted according to the gAMA information alone, and OpenEXR and 
> Radiance HDR files are not subject to any gamma-adjustment as they are 
> defined to carry linear data. This is consistent with handling of the 
> File_Gamma INI setting.
> 
> (Again, as in (A) and (B), input files obviously used as a mere data 
> container will be exempt from this gamma adjustment.)
> 
> - An optional per-file SDL setting "file_gamma", to specify the gamma to 
> apply to the raw encoded data, irregardless of the global setting or 
> file format specifications. This allows for using files that do not 
> follow the specification for some reason or another.
> 
> (If an individual file_gamma is specified for an input file, it *will* 
> be subject to the appropriate gamma conversion even if it is obviously 
> used as a mere data container: It is expected that the user knows what 
> he's doing when overriding gamma.)
> 
> - As for colors explicitly specified in the scene file, I do not have a 
> concrete proposal for now, but I'm thinking along the lines of a 
> color/vector function, as in:
> 
>     color gamma( rgbt <0.5,0.5,0.5, 0.2>, 2.2 )
> 
> (note that this would leave the transmit component unchanged) or 
> possibly an infix operator, as in:
> 
>     color rgbt <0.5,0.5,0.5, 0.2> gamma 2.2
> 
> Not sure about it yet; the former is pretty unambiguous, but seems a bit 
> cumbersome to me, while the latter looks much nicer but may provide some 
> pitfalls.
> 
> Then again, maybe the best way to go would be to introduce a new syntax 
> for vectors/colors to be subject to some default gamma correction, as in:
> 
> default_settings {
>   color_gamma 2.2
> }
> ...
> #declare MyPigment = pigment { color rgbt #<0.5,0.5,0.5,0.2> }
> 
> Any distinctive syntax would do; I just happened to pick this one as an 
> example because of its similarity with the current color syntax while 
> alluding to the HTML color syntax. Note that the "#" could actually be 
> defined as a prefix operator, and in that case could also be used in 
> "color red #0.5" or "color rgb #(<0.2,0,2,0,2>*0.3)".
> 
> Maybe we can even go so far as to allow HTML colors in SDL code? Those 
> would automatically be subject to gamma correction.
> 
> Then again, ambiguities would arise whether for instance "#version" 
> would be the version statement, or the version variable subject to gamma 
> correction, so maybe "#" would not be ideal to be used for that purpose. 
> There are other symbols though which are not used at present, such as 
> the caret (^, used in various languages as an infix operator for the 
> pow() function, which would allude to the mathematical background of 
> gamma adjustment), dollar ($), at (@), percent (%, though that's 
> typically associated with the modulus function) or tilde (~, used in 
> some languages to denote binary inverse). Grave (`) is also still 
> available (though it's possibly too easy to mix up with single quote), 
> as well as the backslash (\). (If unicode characters were an option, I 
> would suggest \u0393 for obvious reasons - but only because I don't 
> intend to use gamma pre-corrected colors frequently :-))
> 
> Then again, it could be simply ruled that the "#" as an operator must 
> either be followed by a number literal, vector literal ("<...>"), or 
> parenthesized expression ("(...)")... or possibly a 6-digit hexadecimal 
> value :-).
> 
> (The more I think about this, the more I like this particular way of 
> handling gamma-pre-corrected colors. The only true caveat I see so far 
> would be the use in include files, which might want their own gamma 
> setting.)
> 
> If we'd go for such a syntax, it might also be prudent to merge the 
> "file_gamma" and "color_gamma" into a single "gamma" statement.
> 
> 
> So, having said all that: Any comments / corrections / further suggestions?



I completely agree with all of your points and I also think your 
proposed solution is the right way to go.
A minor issue would be that I do not see the need for a global SDL 
"file_gamma" setting but I guess it will not hurt either.
I have nothing to say about the SDL color definitions as I do always 
define colors in a linear way and do never use "colors.inc" and that 
like. So my only concern would be that (as I'm a bit lazy) no additional 
typing on my side would be required.


What I have to add are a few notes about file-format gamma handling:

PNG
there is also a sRGB chunk that has even higher priority than the gAMA 
chunk. So if an sRGB chunk is present the gAMA chunk (and its content) 
should be ignored and the sRGB transfer function (close to 2.2) should 
be used to transform the data into linear color space.
If no gAMA chunk and no sRGB chunk is present the PNG/W3C recommendation 
  says to handle the file in the same way is if a sRGB chunk were present.
It would be nice to actually use the sRGB transfer function - when 
approbate - instead of the simple 2.2 exponent but currently libpng has 
no support for this (it is on the libpng TODO list since quite a while).

BMP
since almost 15 years there is a "BITMAPV4HEADER" defined in WinGDI.h 
and the usage of it would make BMP files 'gamma-aware' in the same way 
as PNG. Later MS did even define a "BITMAPV5HEADER" that has full 
support for colorimetric information including ICC profiles.
I have tried very hard to find any such BMP file or any application 
(including all from Microsoft itself I could get my hands on) that would 
write such a file and did not find a single one.
The recommendation from Microsoft is to assume that all BMP's are in 
sRGB color space.

JPG
per W3C recommendation in sRGB color space in case no ICC profile is 
present.

TGA
there is a 'newer' TGA specification 2.0 (from 1989!) that defines a 
'footer' with additional metadata including gamma information. Such a 
TGA file would also be 'gamma-aware' like PNG.
But I'm not aware of any contemporary application that writes or 
recognizes such a footer. I was also unable to find such a file anywhere 
- and I really tried hard.
Most (but not all) TGA files you'll find 'in the wild' are 2.2 gamma 
pre-corrected.

PGM/PBM/PPM/PNM
no gamma information at all and the commonly used gamma correction (or 
its absence) is a matter of wild guessing.

OpenEXR/Radiance HDR
per definition in linear color space.
Just a side note: Radiance files in the xyz(e) format and OpenEXR can 
also store 'out of gamut' colors (i.e. one or two color components with 
negative values) and this seems to be fully supported by POV-Ray.


did I forget something, GIF? not much to say there but usually gamma 
corrected in between 1.4 and 2.4 - its a matter of guessing again.

-Ive


Post a reply to this message

Copyright 2003-2023 Persistence of Vision Raytracer Pty. Ltd.