Skip to content

Commit da593d0

Browse files
committed
Merge pull request godotengine#111897 from allenwp/environment-adj-prioritize-old-behaviour
Improve `Environment` adjustments (favor old behavior and quality).
2 parents fe4cc92 + 0c7f013 commit da593d0

File tree

5 files changed

+70
-46
lines changed

5 files changed

+70
-46
lines changed

doc/classes/Environment.xml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,19 +36,19 @@
3636
</methods>
3737
<members>
3838
<member name="adjustment_brightness" type="float" setter="set_adjustment_brightness" getter="get_adjustment_brightness" default="1.0">
39-
The global brightness value of the rendered scene. Effective only if [member adjustment_enabled] is [code]true[/code].
39+
Applies a simple brightness adjustment to the rendered image after tonemaping. To adjust scene brightness use [member tonemap_exposure] instead, which is applied before tonemapping and thus less prone to issues with bright colors. Effective only if [member adjustment_enabled] is [code]true[/code].
4040
</member>
4141
<member name="adjustment_color_correction" type="Texture" setter="set_adjustment_color_correction" getter="get_adjustment_color_correction">
4242
The [Texture2D] or [Texture3D] lookup table (LUT) to use for the built-in post-process color grading. Can use a [GradientTexture1D] for a 1-dimensional LUT, or a [Texture3D] for a more complex LUT. Effective only if [member adjustment_enabled] is [code]true[/code].
4343
</member>
4444
<member name="adjustment_contrast" type="float" setter="set_adjustment_contrast" getter="get_adjustment_contrast" default="1.0">
45-
The global contrast value of the rendered scene (default value is 1). Effective only if [member adjustment_enabled] is [code]true[/code].
45+
Increasing [member adjustment_contrast] will make dark values darker and bright values brighter. This simple adjustment is applied to the rendered image after tonemaping. When set to a value greater than [code]1.0[/code], [member adjustment_contrast] is prone to clipping colors that become too bright or too dark. Effective only if [member adjustment_enabled] is [code]true[/code].
4646
</member>
4747
<member name="adjustment_enabled" type="bool" setter="set_adjustment_enabled" getter="is_adjustment_enabled" default="false">
4848
If [code]true[/code], enables the [code]adjustment_*[/code] properties provided by this resource. If [code]false[/code], modifications to the [code]adjustment_*[/code] properties will have no effect on the rendered scene.
4949
</member>
5050
<member name="adjustment_saturation" type="float" setter="set_adjustment_saturation" getter="get_adjustment_saturation" default="1.0">
51-
The global color saturation value of the rendered scene (default value is 1). Effective only if [member adjustment_enabled] is [code]true[/code].
51+
Applies a simple saturation adjustment to the rendered image after tonemaping. When [member adjustment_saturation] is set to [code]0.0[/code], the rendered image will be fully converted to a grayscale image. Effective only if [member adjustment_enabled] is [code]true[/code].
5252
</member>
5353
<member name="ambient_light_color" type="Color" setter="set_ambient_light_color" getter="get_ambient_light_color" default="Color(0, 0, 0, 1)">
5454
The ambient light's [Color]. Only effective if [member ambient_light_sky_contribution] is lower than [code]1.0[/code] (exclusive).

drivers/gles3/shaders/effects/post.glsl

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -86,16 +86,6 @@ vec3 apply_color_correction(vec3 color) {
8686
#endif // USE_1D_LUT
8787
#endif // USE_COLOR_CORRECTION
8888

89-
#ifdef USE_BCS
90-
vec3 apply_bcs(vec3 color) {
91-
color = mix(vec3(0.0), color, brightness);
92-
color = mix(vec3(0.5), color, contrast);
93-
color = mix(vec3(dot(vec3(1.0), color) * 0.33333), color, saturation);
94-
95-
return color;
96-
}
97-
#endif
98-
9989
in vec2 uv_interp;
10090

10191
layout(location = 0) out vec4 frag_color;
@@ -140,12 +130,33 @@ void main() {
140130
#endif // USE_GLOW
141131

142132
color.rgb = srgb_to_linear(color.rgb);
133+
143134
color.rgb = apply_tonemapping(color.rgb, white);
144-
color.rgb = linear_to_srgb(color.rgb);
145135

146136
#ifdef USE_BCS
147-
color.rgb = apply_bcs(color.rgb);
148-
#endif
137+
// Apply brightness:
138+
// Apply to relative luminance. This ensures that the hue and saturation of
139+
// colors is not affected by the adjustment, but requires the multiplication
140+
// to be performed on linear-encoded values.
141+
color.rgb = color.rgb * brightness;
142+
143+
color.rgb = linear_to_srgb(color.rgb);
144+
145+
// Apply contrast:
146+
// By applying contrast to RGB values that are perceptually uniform (nonlinear),
147+
// the darkest values are not hard-clipped as badly, which produces a
148+
// higher quality contrast adjustment and maintains compatibility with
149+
// existing projects.
150+
color.rgb = mix(vec3(0.5), color.rgb, contrast);
151+
152+
// Apply saturation:
153+
// By applying saturation adjustment to nonlinear sRGB-encoded values with
154+
// even weights the preceived brightness of blues are affected, but this
155+
// maintains compatibility with existing projects.
156+
color.rgb = mix(vec3(dot(vec3(1.0), color.rgb) * (1.0 / 3.0)), color.rgb, saturation);
157+
#else
158+
color.rgb = linear_to_srgb(color.rgb);
159+
#endif // USE_BCS
149160

150161
#ifdef USE_COLOR_CORRECTION
151162
color.rgb = apply_color_correction(color.rgb);

scene/resources/environment.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1246,7 +1246,7 @@ void Environment::_bind_methods() {
12461246

12471247
ADD_GROUP("Tonemap", "tonemap_");
12481248
ADD_PROPERTY(PropertyInfo(Variant::INT, "tonemap_mode", PROPERTY_HINT_ENUM, "Linear,Reinhard,Filmic,ACES,AgX"), "set_tonemapper", "get_tonemapper");
1249-
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "tonemap_exposure", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_tonemap_exposure", "get_tonemap_exposure");
1249+
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "tonemap_exposure", PROPERTY_HINT_RANGE, "0,4,0.01,or_greater"), "set_tonemap_exposure", "get_tonemap_exposure");
12501250
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "tonemap_white", PROPERTY_HINT_RANGE, "1,16,0.01,or_greater"), "set_tonemap_white", "get_tonemap_white");
12511251

12521252
// SSR
@@ -1522,9 +1522,9 @@ void Environment::_bind_methods() {
15221522

15231523
ADD_GROUP("Adjustments", "adjustment_");
15241524
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "adjustment_enabled", PROPERTY_HINT_GROUP_ENABLE), "set_adjustment_enabled", "is_adjustment_enabled");
1525-
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "adjustment_brightness", PROPERTY_HINT_RANGE, "0.01,8,0.01"), "set_adjustment_brightness", "get_adjustment_brightness");
1526-
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "adjustment_contrast", PROPERTY_HINT_RANGE, "0.01,8,0.01"), "set_adjustment_contrast", "get_adjustment_contrast");
1527-
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "adjustment_saturation", PROPERTY_HINT_RANGE, "0.01,8,0.01"), "set_adjustment_saturation", "get_adjustment_saturation");
1525+
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "adjustment_brightness", PROPERTY_HINT_RANGE, "0.0,2.0,0.01,or_greater"), "set_adjustment_brightness", "get_adjustment_brightness");
1526+
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "adjustment_contrast", PROPERTY_HINT_RANGE, "0.75,1.25,0.005,or_less,or_greater"), "set_adjustment_contrast", "get_adjustment_contrast");
1527+
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "adjustment_saturation", PROPERTY_HINT_RANGE, "0.0,2.0,0.01,or_less,or_greater"), "set_adjustment_saturation", "get_adjustment_saturation");
15281528
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "adjustment_color_correction", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D,Texture3D"), "set_adjustment_color_correction", "get_adjustment_color_correction");
15291529

15301530
// Constants

servers/rendering/renderer_rd/shaders/effects/tonemap.glsl

Lines changed: 36 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -329,13 +329,15 @@ vec3 tonemap_agx(vec3 color) {
329329
}
330330

331331
vec3 linear_to_srgb(vec3 color) {
332-
// Clamping is not strictly necessary for floating point nonlinear sRGB encoding,
333-
// but many cases that call this function need the result clamped.
334-
color = clamp(color, vec3(0.0), vec3(1.0));
335332
const vec3 a = vec3(0.055f);
336333
return mix((vec3(1.0f) + a) * pow(color.rgb, vec3(1.0f / 2.4f)) - a, 12.92f * color.rgb, lessThan(color.rgb, vec3(0.0031308f)));
337334
}
338335

336+
vec3 srgb_to_linear(vec3 color) {
337+
const vec3 a = vec3(0.055f);
338+
return mix(pow((color.rgb + a) * (1.0f / (vec3(1.0f) + a)), vec3(2.4f)), color.rgb * (1.0f / 12.92f), lessThan(color.rgb, vec3(0.04045f)));
339+
}
340+
339341
#define TONEMAPPER_LINEAR 0
340342
#define TONEMAPPER_REINHARD 1
341343
#define TONEMAPPER_FILMIC 2
@@ -446,13 +448,6 @@ vec3 apply_glow(vec3 color, vec3 glow, float white) {
446448
}
447449
}
448450

449-
vec3 apply_bcs(vec3 color, vec3 bcs) {
450-
color = mix(vec3(0.0f), color, bcs.x);
451-
color = mix(vec3(0.5f), color, bcs.y);
452-
color = mix(vec3(dot(vec3(1.0f), color) * 0.33333f), color, bcs.z);
453-
454-
return color;
455-
}
456451
#ifdef USE_1D_LUT
457452
vec3 apply_color_correction(vec3 color) {
458453
color.r = texture(source_color_correction, vec2(color.r, 0.0f)).r;
@@ -928,23 +923,39 @@ void main() {
928923
}
929924
#endif
930925

931-
bool convert_to_srgb = bool(params.flags & FLAG_CONVERT_TO_SRGB);
932-
if (convert_to_srgb) {
933-
color.rgb = linear_to_srgb(color.rgb); // Regular linear -> SRGB conversion.
934-
}
935-
936926
if (bool(params.flags & FLAG_USE_BCS)) {
937-
color.rgb = apply_bcs(color.rgb, params.bcs);
938-
}
939-
940-
if (bool(params.flags & FLAG_USE_COLOR_CORRECTION)) {
941-
// apply_color_correction requires nonlinear sRGB encoding
942-
if (!convert_to_srgb) {
943-
color.rgb = linear_to_srgb(color.rgb);
927+
// Apply brightness:
928+
// Apply to relative luminance. This ensures that the hue and saturation of
929+
// colors is not affected by the adjustment, but requires the multiplication
930+
// to be performed on linear-encoded values.
931+
color.rgb = color.rgb * params.bcs.x;
932+
933+
color.rgb = linear_to_srgb(color.rgb);
934+
935+
// Apply contrast:
936+
// By applying contrast to RGB values that are perceptually uniform (nonlinear),
937+
// the darkest values are not hard-clipped as badly, which produces a
938+
// higher quality contrast adjustment and maintains compatibility with
939+
// existing projects.
940+
color.rgb = mix(vec3(0.5), color.rgb, params.bcs.y);
941+
942+
// Apply saturation:
943+
// By applying saturation adjustment to nonlinear sRGB-encoded values with
944+
// even weights the preceived brightness of blues are affected, but this
945+
// maintains compatibility with existing projects.
946+
color.rgb = mix(vec3(dot(vec3(1.0), color.rgb) * (1.0 / 3.0)), color.rgb, params.bcs.z);
947+
948+
if (bool(params.flags & FLAG_USE_COLOR_CORRECTION)) {
949+
color.rgb = clamp(color.rgb, vec3(0.0), vec3(1.0));
950+
color.rgb = apply_color_correction(color.rgb);
951+
// When using color correction and FLAG_CONVERT_TO_SRGB is false, there
952+
// is no need to convert back to linear because the color correction
953+
// texture sampling does this for us.
954+
} else if (!bool(params.flags & FLAG_CONVERT_TO_SRGB)) {
955+
color.rgb = srgb_to_linear(color.rgb);
944956
}
945-
color.rgb = apply_color_correction(color.rgb);
946-
// When convert_to_srgb is false, there is no need to convert back to
947-
// linear because the color correction texture sampling does this for us.
957+
} else if (bool(params.flags & FLAG_CONVERT_TO_SRGB)) {
958+
color.rgb = linear_to_srgb(color.rgb);
948959
}
949960

950961
// Debanding should be done at the end of tonemapping, but before writing to the LDR buffer.

servers/rendering/storage/environment_storage.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -793,7 +793,9 @@ void RendererEnvironmentStorage::environment_set_adjustment(RID p_env, bool p_en
793793
ERR_FAIL_NULL(env);
794794

795795
env->adjustments_enabled = p_enable;
796-
env->adjustments_brightness = p_brightness;
796+
// Scale brightness via the nonlinear sRGB transfer function to provide a
797+
// somewhat perceptually uniform brightness adjustment.
798+
env->adjustments_brightness = p_brightness < 0.04045f ? p_brightness * (1.0f / 12.92f) : Math::pow(float((p_brightness + 0.055f) * (1.0f / (1.055f))), 2.4f);
797799
env->adjustments_contrast = p_contrast;
798800
env->adjustments_saturation = p_saturation;
799801
env->use_1d_color_correction = p_use_1d_color_correction;

0 commit comments

Comments
 (0)