Skip to content

Conversation

@kofa73
Copy link
Contributor

@kofa73 kofa73 commented Nov 2, 2025

  • The primaries hue and purity (incl. reversal) sliders now have visual hints (hue, purity);
  • The hue and purity sliders look like in color balance rgb, not like in sigmoid / rgb primaries (there is no white stripe from the neutral position to the selected value, obscuring some of the visual hints)
    • => it may make sense to alter sigmoid and rgb primaries the same way, but I did not include such a change in this PR
  • the black/white, toe / shoulder sliders have white/shoulder on the top, black/toe at the bottom
  • a new 'exposure picker' (camera icon): the module will read the exposure parameters from an early, enabled, preferably unmasked instance of exposure, in order to reflect user adjustments + in-camera exposure compensation and 'highlight preservation' modes. This required changes in _exposure.c_, develop.* and imageop.*. Unlike filmic, no estimate (using hard-coded exposure of 0.7 and reading the EXIF) is used, and no adjustment is done in reload_defaults, as the exposure instance is not yet available when it is called. The previous method (picking the limits based on image content) also remains.
  • in the params, the pivot input (x) coordinate is now stored explicitly, instead of storing a shift. The slider has been renamed to pivot relative exposure, as it displays the value in EV. The value is maintained if black/white relative exposure is changed via the sliders or exposure pickers. => module version upgrade to v7 + migration
    The consequences:
    • the pivot's distance from mid-grey remains constant, therefore if exposure limits are adjusted, the projection of the pivot remains the same (the same input levels are mapped to the same output levels as before). Previously, since the output remained unchanged, but the input changed, the mapping changed, and the region of highest contrast moved.
    • the shape of the curve will change, reflecting the movement of the pivot relative to the mid-grey-to-end-of-exposure-range distance.
    • pivot input (x) will still be enforced to stay inside the exposure range; if you shrink that so much that the pivot is forcibly moved (because it would fall outside the exposure limits), then expand the range again, the pivot will not be restored. For example: your black and white relative exposures were -8 EV and +5 EV. You set your pivot at mid-grey +2 EV. Then, you set a very low white exposure limit, like 1.5 EV -> the pivot will be forced to 2 EV (minus epsilon). Then, you restore your white relative exposure to 5 EV -> the pivot will remain at 2 EV.
    • there are now 2 pivot pickers, since some disliked the idea of the pivot input (x) picker also adjusting the output, since that is done by calculating what the brightness would be if we used the default mid-grey -> mid-grey mapping for the pivot. So, the picker next to pivot relative exposure only changes that slider. In order to set both the input and output value (as was done previously), there's a new picker, placed next to pivot target output. This may be a bit confusing, at first, but if you think about it, it makes no sense to set the output using a picker without also saying the brightness of what region is to be set to that value. Explanatory tooltips are provided.

@TurboGit TurboGit added this to the 5.4 milestone Nov 2, 2025
@TurboGit TurboGit added feature: enhancement current features to improve priority: medium core features are degraded in a way that is still mostly usable, software stutters feature: redesign current features to rewrite scope: UI user interface and interactions scope: image processing correcting pixels labels Nov 2, 2025
@kofa73 kofa73 marked this pull request as draft November 2, 2025 15:35
@kofa73
Copy link
Contributor Author

kofa73 commented Nov 2, 2025

Back to draft, checking an alternative way to calculate pivot y.

kofa73 added 19 commits November 9, 2025 10:12
…m exposure data, using the heuristics from filmic RGB.
…ft-over debug code; inset/outset hard-limited to 0.99
…tter visibility (no bar from neutral position to selected value)
… rotation sliders always painted with reversed hues (showing the effect)
…) to find 'best' exposure instance to read data from
…ce to imageop; refactored finding the 'exposure' instance in develop.c.
…posure (should always be called withe gui_data available)
@kofa73 kofa73 force-pushed the agx-ui-toe-shoulder-sliders-and-primaries-rotations branch from 7fa6e9f to 01e016d Compare November 9, 2025 09:12
@kofa73 kofa73 force-pushed the agx-ui-toe-shoulder-sliders-and-primaries-rotations branch from 01e016d to 9d0621d Compare November 9, 2025 09:14
@kofa73 kofa73 marked this pull request as ready for review November 9, 2025 09:37
@kofa73 kofa73 marked this pull request as draft November 9, 2025 09:47
@kofa73 kofa73 marked this pull request as ready for review November 9, 2025 10:04
Copy link
Member

@TurboGit TurboGit left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A bit frightening so close from the release.

Some style comments and a question. TIA.

@kofa73
Copy link
Contributor Author

kofa73 commented Nov 9, 2025

A bit frightening so close from the release.

Yes, I know. I have not heard any bug reports from anyone, though.

@TurboGit
Copy link
Member

TurboGit commented Nov 10, 2025

  • a new 'exposure picker' (camera icon): the module will read the exposure parameters from an early, enabled, preferably unmasked instance of exposure, in order to reflect user adjustments + in-camera exposure compensation and 'highlight preservation' modes.

Can you tell me more about this? The way it works is clear, but what does it brings. Why the exposure level in exposure module is important, I mean a +2EV in the module don't say anything with the displayed result. We do expect the result to have a centered histogram (that's what we recommend for scene referred). So at the end having +2EV or -2EV should not make a difference. So why is that important? TIA.

EDIT: My point is that is this is not very important maybe we can save an icon.

@kofa73
Copy link
Contributor Author

kofa73 commented Nov 10, 2025

  • a new 'exposure picker' (camera icon): the module will read the exposure parameters from an early, enabled, preferably unmasked instance of exposure, in order to reflect user adjustments + in-camera exposure compensation and 'highlight preservation' modes.

Can you tell me more about this? The way it works is clear, but what does it brings. Why the exposure level in exposure module is important, I mean a +2EV in the module don't say anything with the displayed result. We do expect the result to have a centered histogram (that's what we recommend for scene referred). So at the end having +2EV or -2EV should not make a difference. So why is that important? TIA.

EDIT: My point is that is this is not very important maybe we can save an icon.

This is intended to do something similar, but better, than what filmic rgb does. It reads the camera exposure compensation from the EXIF data, adds 0.7 EV (which is the scene-referred default), multiplies it by some heuristic factors and adjusts the base exposure range of -8 EV to +4 EV. However, this does not take manually set exposure into account (always uses 0.7 EV), messes with EXIF data, and also does not take the new highlight preservation exposure modifications into account.

darktable/src/iop/filmicrgb.c

Lines 3182 to 3193 in d2ebf64

if(dt_image_is_matrix_correction_supported(&self->dev->image_storage)
&& is_scene_referred)
{
// For scene-referred workflow, auto-enable and adjust based on exposure
// TODO: fetch actual exposure in module, don't assume 1.
const float exposure = 0.7f - dt_image_get_exposure_bias(&self->dev->image_storage);
// As global exposure increases, white exposure increases faster than black
// this is probably because raw black/white points offsets the lower bound of the dynamic range to 0
// so exposure compensation actually increases the dynamic range too (stretches only white).
d->black_point_source += 0.5f * exposure;
d->white_point_source += 0.8f * exposure;

People seem to like it:
https://discuss.pixls.us/t/agx-terminology-ui/53264/152, https://discuss.pixls.us/t/agx-terminology-ui/53264/156, https://discuss.pixls.us/t/agx-terminology-ui/53264/143, https://discuss.pixls.us/t/agx-terminology-ui/53264/229

We cannot do this automatically (the exposure module has not computed the exposure when reload_defaults is called), so the next best thing is the button.

@TurboGit
Copy link
Member

As I said the way it works is clear to me. My point is what does it brings? People like it, maybe... But I'm not convinced (yet) that this is really useful. And having something similar in FilmicRGB is not an argument :)

The meaning I see is that we consider that the exposure as set in the exposure module is meant to center the histogram. And this is the base of some setting for the curve in AgX. Is that right? And if so, is that really important. The current picker, "reading" the image and determining the black/white exposure seems seems a better way.

Again, I'm just trying to understand if this new extra button is really needed.

@kofa73
Copy link
Contributor Author

kofa73 commented Nov 10, 2025

I don't use it, but I guess people like it because they find it useful. 95% wanted it in some shape or form, either as a default (which 2/3 preferred, but we cannot do) or as a button. They say the picker that actually uses the image content gives results that are 'too harsh'.

@TurboGit
Copy link
Member

95% wanted out of 21 voters :)

@TurboGit
Copy link
Member

I'll continue my testing/review...

@vtyrtov
Copy link
Contributor

vtyrtov commented Nov 10, 2025

Again, I'm just trying to understand if this new extra button is really needed.

The "camera" button is useful for images that are deliberately darkened when shooting (night shots or "golden hour at night"). Those when the histogram should be shifted to the left or right to embody the photographer's idea

@MStraeten
Copy link
Collaborator

MStraeten commented Nov 10, 2025

… people like it because they find it useful.

That might be so because it results in a more realistic ev range

The default expects a range of 16.5 ev which results in dull highlights since most cameras doesn’t capture this range. That requires a manual correction of white relative exposure. Even if the automatic calculation like in filmic rgb is far from being perfect that about 2 ev reduced ev range value above mid grey gives a better starting point.

And a better starting point - often good enough - is found useful;)

but instead of adding a further setting button (the pickers already can be used to get a better initial setting) the initial setting for white relative exposure might be calculated instead of being hardcoded. (The black relative exposure isn‘t that sensitive to initial setting)

@kofa73
Copy link
Contributor Author

kofa73 commented Nov 10, 2025

but instead of adding a further setting button (the pickers already can be used to get a better initial setting) the initial setting for white relative exposure might be calculated instead of being hardcoded

I haven't found a way to do that. filmic rgb really just guesses: it uses a hard-coded 0.7 for the exposure correction, does not take the recently introduced highlight preservation (in-camera DR magic, underexposure) into account, and reads directly from the EXIF data. All of that is really the responsibility of the exposure module, which does that, and calculates an overall correction. However, at the time reload_defaults is called on AgX, the value is not yet available from exposure, and I do not know of any other point where I could get that info.

I did not (and do not) want to duplicate all the calculation exposure does.

@kofa73
Copy link
Contributor Author

kofa73 commented Nov 10, 2025

The black relative exposure isn‘t that sensitive to initial setting

We could actually change the auto pickers ('camera' + auto tune exposure) so they only care about white, and set black automatically to maintain the shape of the curve (the black -> grey and grey -> white distance ratios), subject to the hard limits. The individual white / black pickers would continue to modify only the corresponding value.

Copy link
Member

@TurboGit TurboGit left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, works for me. I'll merge this now to get some more field testing. Thanks for the work.

Can you open an issue to discuss the change of colored sliders in sigmoid and rgb primaries to look like AgX and ColorBalanceRGB? TIA.

@TurboGit TurboGit merged commit cba4ab0 into darktable-org:master Nov 11, 2025
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature: enhancement current features to improve feature: redesign current features to rewrite priority: medium core features are degraded in a way that is still mostly usable, software stutters scope: image processing correcting pixels scope: UI user interface and interactions

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants