Can someone please help me understand the details of tone mapping? See my questions throughout this post.
My understanding (I put some example numbers in there, from thin air):
- Tonemapping brings a range of color values (ex. 0.5 to 2.0) into a range the computer can output (0.0 to 1.0).
- Tonemapping also uses a curved formula based on what your average luminance value and the highest value in the scene is. So if the scene is darker, more values (ex. perhaps 0.0 to 0.8) will be used for darker colors.
- The value from my tonemapping formula will be multiplied to my scene's color.
So, I would expect results like this:
0.2 average scene luminance
1.1 brightest pixel on screen
Scene image values (0.0 to 0.4) mapped to output values (0.0 to 0.6). (largest range)
Scene image values (0.4 to 1.1) mapped to output values (0.6 to 1.0).
Another Example I would expect:
0.8 average scene luminance
2.0 brightest pixel on screen
Scene image values (0.0 to 0.6) mapped to output values (0.0 to 0.2).
Scene image values (0.6 to 1.0) mapped to output values (0.2 to 0.8). (largest range)
Scene image values (1.0 to 2.0) mapped to output values (0.8 to 1.0).
Reinhard's tonemapping in HLSL (is my math ok?)
avgLum = average scene luminance;
static const float MIDDLE_GREY = 0.72f; /// WHY IS THIS 0.72???????? I HATE MAJIK NUMBERS
newCol = (MIDDLE_GREY / avgLum) * pxColor;
static const float L_WHITE = 1.5f; // I assume this is just our max value before it's pure white
newCol = newCol * (1.0f + newCol / L_WHITE) / (1.0f + newCol);
Some examples!!!
-------------------------------------------------------------------------------
avgLum = 0.2
pxColor = {1.0, 1.0, 1.0}
newCol = (0.72 / 0.2) * {1.0, 1.0, 1.0};
newCol = newCol * (1.0f + newCol / 1.5) / (1.0f + newCol);
newCol = 12.24 / 4.6;
newCol = {2.66, 2.66, 2.66} ???? WTF Why is my 1.0 now being blown out to 2.6?
-------------------------------------------------------------------------------
avgLum = 0.2
pxColor = {0.1, 0.1, 0.1}
newCol = (0.72 / 0.2) * {0.1, 0.1, 0.1};
newCol = newCol * (1.0f + newCol / 1.5) / (1.0f + newCol);
newCol = 0.0864 / 1.36;
newCol = {0.0635,0.0635,0.0635} ??? why did my 0.1 get darker???
-------------------------------------------------------------------------------
avgLum = 0.5
pxColor = {0.5, 0.5, 0.5}
newCol = (0.72 / 0.5) * {0.5, 0.5, 0.5};
newCol = newCol * (1.0f + newCol / 1.5) / (1.0f + newCol);
newCol = 1.0656 / 1.72;
newCol = {0.62,0.62,0.62} ??? This actually seems ok, other than why did it get brighter? Shouldn't this be a perfect 0.5?
Please see my questions above, thanks for any help. This is confusing. The biggest question is why are some ppl putting 0.72 into a MIDDLE_GRAY variable. I've seen several ppl do this.
Thanks
Jeff.