Skip to content

Improve Environment adjustments (favor old behavior and quality).#111897

Merged
Repiteo merged 1 commit into
godotengine:masterfrom
allenwp:environment-adj-prioritize-old-behaviour
Oct 23, 2025
Merged

Improve Environment adjustments (favor old behavior and quality).#111897
Repiteo merged 1 commit into
godotengine:masterfrom
allenwp:environment-adj-prioritize-old-behaviour

Conversation

@allenwp

@allenwp allenwp commented Oct 22, 2025

Copy link
Copy Markdown
Contributor

This PR supersedes:

This commit changes adjustments to behave as follows for all rendering configurations:

  • Apply brightness to linear-encoded values, preventing hue and saturation from being affected.
  • Apply contrast to perceptually uniform (nonlinear sRGB-encoded) values, matching existing behavior when HDR 2D is disabled and producing optimal visual quality.
  • Apply saturation with even color channel weights on perceptually uniform (nonlinear sRGB-encoded) values. This causes brightness of certain colors to change, but matches existing behavior when HDR 2D is disabled.

Adjustments are applied after glow and tonemapping to match existing behavior.

Summary

This PR is an alternative approach to the following:

The saturation adjustment can be further improved as a followup PR:

HDR 2D Disabled Status Summary
Brightness Modified Improved visual quality
Contrast No change  
Saturation No change Brightness of some colours changes when saturation changes
HDR 2D Enabled Status Summary
Brightness Modified Now perceptually uniform (better for animations & matches HDR 2D disabled)
Contrast Modified Improved visual quality and usability
Saturation Modified Now maches HDR 2D disabled
Performance  
HDR 2D (Mobile / Forward+ with no color correction LUT) Regression (full round trip to and from nonlinear sRGB encoding)
Other configurations No change

Rationale and screenshots

Rationale and screenshots for this PR can be found in godotengine/godot-proposals#13195.

Changes and improvements

The following is a summary of the key points that are further detailed in the proposal.

Brightness

HDR 2D Disabled

Problem: When HDR 2D is disabled in Godot 4.5 and earlier, the brightness adjustment is applied as a scaling of nonlinear sRGB-encoded values. This is incorrect in terms of CIE colorimetry and results in a change in saturation, hue, and contrast when brightness is adjusted.

To correct this issue, scaling is applied to linear-encoded RGB values, which results in relative luminance being scaled directly without affecting hue or saturation:

Original scene Godot 4.5 HDR 2D disabled This PR
2025-10-22 (1) old-brightness fixed

This PR also removes clipping from the conversion to nonlinear sRGB encoding, which may have impact on some scenes with bright values. A future PR could add back in explicit user-controlled clipping of bright values before applying adjustments, but I believe that the new behaviour in this PR is generally preferred:

Original scene Godot 4.5 HDR 2D disabled This PR
Image Image Image

HDR 2D Enabled

Problem: When HDR 2D is enabled in Godot 4.3 through 4.5, the brightness adjustment is not perceptually uniform, which makes it difficult to use as a "fade to black" effect.

In this video I demonstrate the two approaches to the brightness adjustment: brightness fades in and out with the sRGB transfer function and then without (cycling back and forth between the two). Note that without the sRGB transfer function, the image fully darkens very suddenly, making for a more abrupt transition:

brightess-scale.mp4

This PR corrects this issue by making the brightness adjustment more perceptually uniform when HDR 2D is enabled by using the nonlinear sRGB transfer function. The brightness adjustment is still correctly applied to linear-encoded RGB values.

Contrast

Problem: The contrast adjustment heavily darkens the image when HDR 2D is enabled and is very difficult to use and fine-tune. This problem happens because the contrast pivot is at a linear value of 0.5 instead of a more common value of around 0.18 (middle grey) or 0.214041140482232 (sRGB 50%).

This PR corrects this problem by changing the contrast pivot point to be 0.214 (sRGB 50%), which better matches industry standards. The contrast is further improved by being applied to perceptually uniform R, G, and B values.

Photoshop 26.1 contrast Godot 4.5 HDR 2D enabled (0.5 pivot) This PR (0.214 pivot)
Image Image Image

Saturation

Problem: Low-luminance colours change in apparent brightness when saturation is changed. A prime example is deep blue colours which appear to brighten when saturation is decreased and darken when saturation is increased.

This problem remains unresolved with this PR, but could be solved in a future PR.

Docs

I suggest to use tonemap_exposure instead of scene brightness because camera_attributes exposure does not affect scenes without a camera that target a "canvas" background mode. But currently, tonemap_exposure is just not implemented at all for the Compatibility renderer.

Notes to reviewers

  1. This leaves Image.adjust_bcs with the legacy behaviour. It might make sense to update this as well to match the new environment behaviour, but I believe this is better suited for a followup PR if others want this. (My plan is to not touch this existing function; I don't have the time to look into this.)

@AThousandShips AThousandShips added this to the 4.x milestone Oct 22, 2025
@allenwp allenwp changed the title Improve Environment adjustments (favor old behavior). Improve Environment adjustments (favor old behavior and quality). Oct 22, 2025
@allenwp allenwp marked this pull request as ready for review October 22, 2025 17:42
@allenwp allenwp requested review from a team as code owners October 22, 2025 17:42

@clayjohn clayjohn left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Discussed in the rendering meeting today. Thanks for discussing this and being responsive to feedback. This approach looks great!

@clayjohn clayjohn modified the milestones: 4.x, 4.6 Oct 23, 2025
Comment thread scene/resources/environment.cpp Outdated
Comment thread doc/classes/Environment.xml Outdated
Comment thread doc/classes/Environment.xml Outdated
…HDR 2D contrast.

This commit changes adjustments to behave as follows for all rendering configurations:

- Apply brightness to linear-encoded values, preventing contrast, saturation, and hue from being affected.
- Apply contrast to perceptually uniform (nonlinear sRGB-encoded) values, matching existing behavior when HDR 2D is disabled and producing optimal visual quality.
- Apply saturation with even color channel weights. This causes brightness of certain colors to change, but matches existing behavior when HDR 2D is disabled.

Adjustments are applied after glow and tonemapping to match existing behavior.
@allenwp allenwp force-pushed the environment-adj-prioritize-old-behaviour branch from 9876d9a to 0c7f013 Compare October 23, 2025 15:09
@Repiteo Repiteo merged commit da593d0 into godotengine:master Oct 23, 2025
20 checks passed
@Repiteo

Repiteo commented Oct 23, 2025

Copy link
Copy Markdown
Contributor

Thanks!

@allenwp allenwp deleted the environment-adj-prioritize-old-behaviour branch October 23, 2025 22:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Improve Environment adjustments. HDR 2D affects 3D glow and BCS

4 participants