filmic v4 on the way

I am trying to understand the details of the tone mapping formulas in filmic v4, to see if I can get some “inspiration”, and I have some observations that would like to get confirmed by the experts.

First of all I would like to understand the behavior of the tone mapping curve alone. I might come back to the saturation and hue control in another post…

Let’s put aside the highlights reconstruction, and consider the simplest version with channel-by-channel tone mapping (filmic_split_v2). For simplicity, let’s initially see what happens to the mid-grey point, step-by-step.

The black and white points are defined in EV values with respect to mid-grey. That is, a “white relative exposure” of +5EV means white = 32 * mid-grey. Right?

For a symmetric dynamic range (black_exposure = -white_exposure), the log conversion maps the linear values in the following way:

  • log(black) = 0
  • log(mid-grey) = 0.5
  • log(white) = 1

Next, the spline function maps log values back to the linear domain: out = spline(log(in)).
We have:

  • spline(log(black)) = 0
  • spline(log(mid-grey)) = pow(mid-grey, 1/hardness)
  • spline(log(white)) = 1

That is, the black and white points are mapped to 0 and 1 respectively, and the mid-grey point is mapped to mid-grey raised to the 1/hardness power. Am I right?

Here is a typical example of tone-mapping curve wit a slight contrast and a symmetric dynamic range:
Screen Shot 2020-06-17 at 8.18.29 PM

The plot in the UI shows the log-to-linear mapping of the spline curve, but does not include the final power function, controlled by the “hardness” parameter.

I find it interesting to look at the linear-in -> linear-out curve as well, that is the result of the full chain out = pow(spline(log(in)), hardness), so I modified the UI to plot this:
Screen Shot 2020-06-17 at 8.21.47 PM

Here is the same, but with the horizontal/vertical scales going from 0 to 0.25 to zoom on the region around and below mid-grey. The mid-grey point is also marked in the plot:

Screen Shot 2020-06-17 at 8.34.57 PM

One can see that the tone-mapping curve is steeper than the diagonal line below mid-grey, and is flatter than the diagonal at the mid-grey point. That is, the contrast in the mid-tones is lowered, even if the contrast parameter is > 1. I have played a bit with the various parameters, and as far as I can see this is always the case, except for very high values of the contrast… is this intentional?

I was also trying to achieve a “neutral” rendering in which the shadows and mid-tones are left unchanged and only the highlights are compressed. This would correspond to a curve that lies on the diagonal up to the mid-grey point (or higher), and then bends down to compress the highlights. However, I have not found any combination of parameters that behaves like this.
Setting both the contrast and the hardness to 1 (that is, a flat spline curve that maps mid-grey to mid-grey without an additional power function at the end), I obtain instead a curve that severely clips the dark end:
Screen Shot 2020-06-17 at 8.39.30 PM

Is there a way to achieve “neutral shadows” with filmic V4?

@aurelienpierre I hope you find the time to read this rather long post…


1 Like


The spline maps from log to “gamma”, since you see log(mid-grey) -> mid-grey^(1 / hardness), and this gets later mapped to linear through x^hardness. It’s the same things as the log2/log10 film sensitometry curves, conceptually.

Yes, this comes from the filmic curve imposing a first-order derivative = 0.0 at 0%. You can relax that constraint by setting “shadows contrast” to “soft” in the options tab. “Hard” uses a 4th order polynomial constraining it to be tangent to the horizontal, while “soft” uses a 3rd order polynomial that only constrains the lerping conditions with the latitude.

1 Like

Thanks! However, I see a similar behavior when using the soft option:

Screen Shot 2020-06-17 at 9.40.02 PM

You have the log transfer function at the beginning. If you set hardness & contrast == 1, you are asking the interpolation to pass through (0, 0), (0.5, 0.18) and (1, 1) while ensuring continuity of the the first order derivative around the latitude. My guess is that puts too much “tension” on the spline and produces overshoot/undershoot. Neutral blacks + highlights compression have never been a design goal for filmic, so they would need a different spline.

Ok, understood.

Regarding the slope of the tone mapping curve around the mid-grey point, I have tried to set the shadows contrast to “soft”, but I see no difference in the mid-tones:

Screen Shot 2020-06-17 at 10.02.42 PM

Enabling the auto adjustment of the hardness gives a smooth transition to zero, but the tone curve flattens well before the mid-grey point…

I am insisting on this point because I have the idea that a contrast boost should mainly affect the mid-tones… not a criticism, just trying to understand :wink:

Yes, this is because the latitude is a straight line no matter what. You should read the details of the S curve here :

That depends on your latitude width, I think. But I don’t really understand your graph. It should pass through (1,1) if you applied the output power on it, why does it not ?

Contrast is the slope of the linear central part (midtones indeed), so it also affects extreme values because of the continuity of the gradient, in the way that… well, whatever the slope is, it should smoothly end up at (0,0) and (1, 1).

1 Like

No, no… that’s the whole tone mapping curve, from linear_in to linear_out, so out=1 is mapped to in=white. Hence the curve passes through (1, white)…

Didn’t help, but there’s a new parallel thread with nightly windows builds. That worked.
Thanks anyway!

First off, a big thanks for the improved filmic! :+1:

When I select “scene-referred” like in your screenshot (with disabled base curve) nothing is applied on opening. I use the latest nightly from the parallel Windows thread.

Please note that the changed setting will not take effect until you restart darktable. Also, note that the scene-referred workflow defaults are only applied to new edits and when you discard the history stack on an existing edit.

Discarding the history indeed works, opening an unedited pic not. But that’s a great workaround - thanks!

To be clear when I say ‘new edit’ I mean an image that has never been opened in the darkroom. As soon as you open an image in the darkroom, darktable auto-applies some settings and this is considered part of the ‘edit’.

OK, I started again from scratch, new database, no .xmp, now it works fine.
Time to donate.


Would you give a link to the parallel thread, please?

Thanks, especially for the quick response. :smile:

Since that message, I have come across some data that seems to support the +1 EV.

First, some background: ISO 12232:2019 defines various ways to compute an ISO value. Out of those, CIPA mandates the use of either SOS (Standard Output Sensitivity) or REI (Recommended Exposure Index), which are computed as \frac{10\,\text{lx}\cdot\text{s}}{H} where H, for an average scene, is a mid-tone exposure. More specifically, for SOS on a camera that produces 8-bit output, H is the exposure required to produce an image signal level of 118 (so middle gray in sRGB), and for REI, H is the arithmetic mean exposure recommended by the camera provider.

Now, there is another, saturation-based method, which DxOMark happily applies to RAW files (even though ISO values are not supposed to be reported for RAW files) and then calls “measured ISO”. While highly misleading and very frequently misinterpreted, it is still useful information. Saturation-based ISO speed is computed as \frac{78\,\text{lx}\cdot\text{s}}{H} where H is the exposure that saturates the output. (Processed output according to the standard, RAW output in the case of DxOMark.) That value of 78 was chosen so that, for a camera where saturation-based ISO speed coincides with an exposure index (SOS or REI), there is approximately 41% (½ EV) of headroom above 100% reflectance. (We can indeed verify that 1.41 \cdot \frac{100}{18} \cdot 10\,\text{lx}\cdot\text{s} \simeq 78\,\text{lx}\cdot\text{s}.)

Now, cameras tend to deviate from this coincidence, generally in the direction of having more highlight headroom (except for a few Panasonic cameras as I mentioned previously). An analysis of DxOMark’s data by Bill Claff suggests that at least as of 2014, the deviation was heavily centered around 0.33 EV of additional headroom relative to the ISO setting (on top of the ½ EV accounted for by ISO speed), for a total of 0.83 EV of headroom above 100 %.

That means that for a shot metered by an average camera (as of 2014), to get 100 % reflectance at 100 % in the RAW and 18 % reflectance at 18 %, we need to apply +0.83 EV to the RAW values.

A bit OT: At the start of the tutorial there are five pictures in lighttable. You once did a video on the top, left picture that I can no longer find online. I know it is old, but I would like to watch it again. Would you be able to give me a link to it?

just played around with the new highlights reconstrution options and I think it’s really interesting… seems to work well

legacy highlights reconstruction

filmic4 highlights recontruction

1 Like