Tone map theory questions.

Started by
2 comments, last by BBeck 7 years ago

Hi Forum!

I decided to re-design my tone map pass.
As I understand, any tonemap operator maps from HDR[0, inf] to [0,1]:


HDRColor   Uncarted2 Reinh     Filmic
0.0039     0.0013    0.0039    0
0.0063     0.0022    0.0062    0.0001
0.016      0.0058    0.0157    0.0044
0.0256     0.0096    0.025     0.0127
0.041      0.0162    0.0393    0.0307
0.0655     0.0276    0.0615    0.0649
0.1678     0.0802    0.1437    0.2098
0.2684     0.1323    0.2116    0.3249
0.4295     0.2084    0.3005    0.4571
1.0995     0.4256    0.5237    0.7052
1.7592     0.5465    0.6376    0.7973
2.8147     0.6577    0.7379    0.865
7.2058     0.8198    0.8781    0.9436
11.5292    0.8699    0.9202    0.9641
18.4467    0.904     0.9486    0.9773
47.2237    0.9413    0.9793    0.991
75.5579    0.9507    0.9869    0.9944
120.892    0.9566    0.9918    0.9965
21267.64   0.9666    1         1

So, for pure conversion from HDR to LDR, I need to do a simple thing just apply Tone map operator:


float4 main(float4 pos : SV_Position) : SV_Target
{
    float3 color = HDRTex[uint2(pos.xy)].rgb;
    color = TmOp(color);

    return float4(color, 1);
}

======================================
Manual luminance (exposure) adjustments
I assume that it is useful in case when for certain level I want to do darker.
IMO it should mimic more time shooter is opened.
TmOp() will squeeze color to [0, 1], but the scene will be artificially darker/brighter, dependent on cb_linearExposureAdjustmet (which is linear in order to do less math in FullHD):


cbuffer Cb {
    float cb_linearExposureAdjustmet; //It is linear and != 0
};

float3 ExposeColor(float3 color)
{
    return color * cb_linearExposureAdjustmet;
}

float4 main(float4 pos : SV_Position) : SV_Target
{
    float3 color = HDRTex[uint2(pos.xy)].rgb;
    color = ExposeColor(color);
    color = TmOp(color);

    return float4(color, 1);
}

Question1: Can it be done via simple multiplication color by exposure, or it’s better to do something different?
Question2: what are other use cases of manual exposure change?

======================================
Eye adaptation.
Used for slow down rapid luminance change.
For example, avg lum was 4, and became 3.
Each frame instead of rendering with 3, I adjust it a little bit higher: 3.9, 3.85, … 3.0.
How I understand, it might be emulated as in previous step, via cb_linearExposureAdjustmet.

Question3: is this correct or am I missing something?

Question3.5: In which other use cases average luminance is useful?

======================================
The next step is “Auto exposure” (it is just my thoughts from old time when I did photo)
As I understand, the idea is:
1. Calculate diapason of luminancies [lowest and highest values],
2. Transform HDR image to this diapason (which is also HDR),
3. Tone map the image from step 2 to LDR [0,1]
It probably gives best diapason for LDR result.

Question4: is this a thing in video game industry? If not, what exactly “Auto exposure” should do?

Thanks in advance!

Advertisement

Exposure is just a simple color mult before the tonemapping. Auto exposure means automatically calculating this exposure value based on scene avg luminance, histogram or something else, but still it doesn't change the tonemapping. It works the same way as for a real-world camera - exposure is manual/auto "brightness setting" and tonemapping is analog film. Shameless plug: some time ago I wrote a lengthy post about auto-exposure in games: https://knarkowicz.wordpress.com/2016/01/09/automatic-exposure/ .

Great article!

Thank you so much, Krzysztof for your help!

Interesting article. I'm still a bit aways from getting up to the level of coding HDR stuff, but I've done some photography over the years and thus understand the subject of light somewhat.

I never imagined HDR for games would have the same complications that exist in the real world with lighting like exposure and white balance. Very informative.

This topic is closed to new replies.

Advertisement