Replies: 2 comments 2 replies
-
For anybody interested, after a long afternoon I was able to resolve my second question. The important detail I was forgetting is that a pixel is determined as an average of several rays. Unlike simple multiplication would, the average operation does not commute with the square root operation! In fact, as the square root is a concave function, one can quickly derive that the gamma-unaware scenario gives a pixel color that will always be at least as dark as in the correct scenario (decoding-encoding), and the difference will be greater when the individual summands in the average vary more (with equality exactly when all the summands are equal). This explains why the shadow regions were effected especially; different rays frequently have a different number of "forth and back" bounces before reaching the light source, leading to unequal contribution to the average --> the shadows turn out too dark if gamma unaware. I am still interested to hear reasoning concerning the first question :) |
Beta Was this translation helpful? Give feedback.
-
Because the math the ray tracer uses assumes linear space, where light intensities add and multiply linearly. For example, if you blend a black (0.0) and a white (1.0) rays in linear space you get: after gamma-encoding you get: which is mid-gray in perceived (gamma) space. In "gamma-unaware" scenario, your black is still 0.0 and your white is still 1.0, but if you use linear math for blending, your result is: which is dark-gray (25% gray) in the perceived space. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
In chapter 9 of the first book, we gamma encode the color values to (approximately) match the color scale the ppm file viewer expects.
To simplify what I am about to say, consider the simple scene with a completely white ambient light (no hit --> return color(1.0,1.0,1.0)), and only one diffuse (0.5,0.5,0.5)-grey ball. (*)
Without the gamma correction, the colors we specify are implicitly in gamma space. In that case, after running the ray tracer, the resulting image shows a completely (0.5,0.5,0.5)-grey ball. By doing the gamma encoding after rendering, we implicitly have changed our initial color space to linear, so we have changed our initial color. The rendered ball has color (0.71,0.71,0.71)-grey only because of the implicit initial color change. Arguably, in order to make a better comparison, the initial color should be kept the same, i.e. considered as being in gamma space and decoded (gamma to linear) before tracing rays. Doing that also leads to a (0.5,0.5,0.5)-grey in the final image, as in the gamma-unaware case.
After looking at the source code, it becomes clear that this equality is not just an edge case: Because the decoding squares the color values and the encoding takes the root of them, and when calculating the ray color the only operation is multiplying two colors, the squares and root cancel (not accounting for rounding error), yielding the same result in the gamma-unaware scenario as when decoding-raytracing-encoding.
This leads me to my first question: If (at least according to wikipedia) one of the reasons for gamma encoding is that it agrees better with human perception than linear encoding, why do we insist on specifying the colors of our objects in linear space (after Chapter 9)?
Now, in order to test my above reasoning, I rendered the diffuse ball (and ground ball) from the final image in both the gamma-unaware and decoding-raytracing-encoding scenario (as described above). To my surprise, the images were indeed different, which contradicts my thoughts. In particular, the gamma-unaware scenario has more pronounced shadows. I cannot explain this, neither find my error. Why is this the case? What am I missing/forgetting/misinterpreting?
(*) Throughout, I specify RGB triplets by their gamma space values.
(I am attaching the two resulting images, where the only difference in source code is whether decoding-encoding is made or not. And besides that and different camera orientation, I made no changes to the source code of the current version on github)
Beta Was this translation helpful? Give feedback.
All reactions