mirror of https://github.com/godotengine/godot
Merge 05bc9f306a into 15ff450680
This commit is contained in:
commit
94e25119b5
|
|
@ -425,11 +425,11 @@
|
|||
Uses a film-like tonemapping curve to prevent clipping of bright values and provide better contrast than [constant TONE_MAPPER_REINHARDT]. Slightly slower than [constant TONE_MAPPER_REINHARDT].
|
||||
</constant>
|
||||
<constant name="TONE_MAPPER_ACES" value="3" enum="ToneMapper">
|
||||
Uses a high-contrast film-like tonemapping curve and desaturates bright values for a more realistic appearance. Slightly slower than [constant TONE_MAPPER_FILMIC].
|
||||
Uses a high-contrast film-like tonemapping curve and desaturates bright values for a more realistic appearance. Slightly slower than [constant TONE_MAPPER_FILMIC] and similar performance to [constant TONE_MAPPER_AGX].
|
||||
[b]Note:[/b] This tonemapping operator is called "ACES Fitted" in Godot 3.x.
|
||||
</constant>
|
||||
<constant name="TONE_MAPPER_AGX" value="4" enum="ToneMapper">
|
||||
Uses a film-like tonemapping curve and desaturates bright values for a more realistic appearance. Better than other tonemappers at maintaining the hue of colors as they become brighter. The slowest tonemapping option.
|
||||
Uses a film-like tonemapping curve and desaturates bright values for a more realistic appearance. Better than other tonemappers at maintaining the hue of colors as they become brighter. Slightly slower than [constant TONE_MAPPER_FILMIC] and similar performance to [constant TONE_MAPPER_ACES].
|
||||
[b]Note:[/b] [member tonemap_white] is fixed at a value of [code]16.29[/code], which makes [constant TONE_MAPPER_AGX] unsuitable for use with the Mobile rendering method.
|
||||
</constant>
|
||||
<constant name="GLOW_BLEND_MODE_ADDITIVE" value="0" enum="GlowBlendMode">
|
||||
|
|
|
|||
|
|
@ -5403,11 +5403,11 @@
|
|||
Uses a film-like tonemapping curve to prevent clipping of bright values and provide better contrast than [constant ENV_TONE_MAPPER_REINHARD]. Slightly slower than [constant ENV_TONE_MAPPER_REINHARD].
|
||||
</constant>
|
||||
<constant name="ENV_TONE_MAPPER_ACES" value="3" enum="EnvironmentToneMapper">
|
||||
Uses a high-contrast film-like tonemapping curve and desaturates bright values for a more realistic appearance. Slightly slower than [constant ENV_TONE_MAPPER_FILMIC].
|
||||
Uses a high-contrast film-like tonemapping curve and desaturates bright values for a more realistic appearance. Slightly slower than [constant ENV_TONE_MAPPER_FILMIC] and similar performance to [constant ENV_TONE_MAPPER_AGX].
|
||||
[b]Note:[/b] This tonemapping operator is called "ACES Fitted" in Godot 3.x.
|
||||
</constant>
|
||||
<constant name="ENV_TONE_MAPPER_AGX" value="4" enum="EnvironmentToneMapper">
|
||||
Uses a film-like tonemapping curve and desaturates bright values for a more realistic appearance. Better than other tonemappers at maintaining the hue of colors as they become brighter. The slowest tonemapping option.
|
||||
Uses a film-like tonemapping curve and desaturates bright values for a more realistic appearance. Better than other tonemappers at maintaining the hue of colors as they become brighter. Slightly slower than [constant ENV_TONE_MAPPER_FILMIC] and similar performance to [constant ENV_TONE_MAPPER_ACES].
|
||||
[b]Note:[/b] [member Environment.tonemap_white] is fixed at a value of [code]16.29[/code], which makes [constant ENV_TONE_MAPPER_AGX] unsuitable for use with the Mobile rendering method.
|
||||
</constant>
|
||||
<constant name="ENV_SSR_ROUGHNESS_QUALITY_DISABLED" value="0" enum="EnvironmentSSRRoughnessQuality">
|
||||
|
|
|
|||
|
|
@ -84,21 +84,14 @@ vec3 tonemap_aces(vec3 color, float p_white) {
|
|||
return color_tonemapped / p_white_tonemapped;
|
||||
}
|
||||
|
||||
// Polynomial approximation of EaryChow's AgX sigmoid curve.
|
||||
// x must be within the range [0.0, 1.0]
|
||||
vec3 agx_contrast_approx(vec3 x) {
|
||||
// Generated with Excel trendline
|
||||
// Input data: Generated using python sigmoid with EaryChow's configuration and 57 steps
|
||||
// Additional padding values were added to give correct intersections at 0.0 and 1.0
|
||||
// 6th order, intercept of 0.0 to remove an operation and ensure intersection at 0.0
|
||||
vec3 x2 = x * x;
|
||||
vec3 x4 = x2 * x2;
|
||||
return 0.021 * x + 4.0111 * x2 - 25.682 * x2 * x + 70.359 * x4 - 74.778 * x4 * x + 27.069 * x4 * x2;
|
||||
}
|
||||
|
||||
// This is an approximation and simplification of EaryChow's AgX implementation that is used by Blender.
|
||||
// This is a simplified glsl implementation of EaryChow's AgX that is used by Blender.
|
||||
// Input: unbounded linear Rec. 709
|
||||
// Output: unbounded linear Rec. 709 (Most any value you care about will be within [0.0, 1.0], thus safe to clip.)
|
||||
// This code is based off of the script that generates the AgX_Base_sRGB.cube LUT that Blender uses.
|
||||
// Source: https://github.com/EaryChow/AgX_LUT_Gen/blob/main/AgXBasesRGB.py
|
||||
// Changes: Negative clipping in input color space without "guard rails" and no chroma-angle mixing.
|
||||
// Repository for this code: https://github.com/allenwp/AgX-GLSL-Shaders
|
||||
// Refer to source repository for other matrices if input/output color space ever changes.
|
||||
vec3 tonemap_agx(vec3 color) {
|
||||
// Combined linear sRGB to linear Rec 2020 and Blender AgX inset matrices:
|
||||
const mat3 srgb_to_rec2020_agx_inset_matrix = mat3(
|
||||
|
|
@ -112,11 +105,13 @@ vec3 tonemap_agx(vec3 color) {
|
|||
-0.85585845117807513559, 1.3264510741502356555, -0.23822464068860595117,
|
||||
-0.10886710826831608324, -0.027084020983874825605, 1.402665347143271889);
|
||||
|
||||
// LOG2_MIN = -10.0
|
||||
// LOG2_MAX = +6.5
|
||||
// MIDDLE_GRAY = 0.18
|
||||
const float min_ev = -12.4739311883324; // log2(pow(2, LOG2_MIN) * MIDDLE_GRAY)
|
||||
const float max_ev = 4.02606881166759; // log2(pow(2, LOG2_MAX) * MIDDLE_GRAY)
|
||||
// Terms of Timothy Lottes' tonemapping curve equation:
|
||||
// c and b are calculated based on a and d with AgX mid and max parameters
|
||||
// using the Mathematica notebook in the source AgX-GLSL-Shaders repository.
|
||||
const float a = 1.36989969378897;
|
||||
const float c = 0.3589386656982;
|
||||
const float b = 1.4325264680543;
|
||||
const float e = a * 0.903916850555009; // = a * d
|
||||
|
||||
// Large negative values in one channel and large positive values in other
|
||||
// channels can result in a colour that appears darker and more saturated than
|
||||
|
|
@ -125,28 +120,25 @@ vec3 tonemap_agx(vec3 color) {
|
|||
// This is done before the Rec. 2020 transform to allow the Rec. 2020
|
||||
// transform to be combined with the AgX inset matrix. This results in a loss
|
||||
// of color information that could be correctly interpreted within the
|
||||
// Rec. 2020 color space as positive RGB values, but it is less common for Godot
|
||||
// to provide this function with negative sRGB values and therefore not worth
|
||||
// Rec. 2020 color space as positive RGB values, but is often not worth
|
||||
// the performance cost of an additional matrix multiplication.
|
||||
// A value of 2e-10 intentionally introduces insignificant error to prevent
|
||||
// log2(0.0) after the inset matrix is applied; color will be >= 1e-10 after
|
||||
// the matrix transform.
|
||||
color = max(color, 2e-10);
|
||||
|
||||
// Do AGX in rec2020 to match Blender and then apply inset matrix.
|
||||
// Apply inset matrix.
|
||||
color = srgb_to_rec2020_agx_inset_matrix * color;
|
||||
|
||||
// Log2 space encoding.
|
||||
// Must be clamped because agx_contrast_approx may not work
|
||||
// well with values outside of the range [0.0, 1.0]
|
||||
color = clamp(log2(color), min_ev, max_ev);
|
||||
color = (color - min_ev) / (max_ev - min_ev);
|
||||
|
||||
// Apply sigmoid function approximation.
|
||||
color = agx_contrast_approx(color);
|
||||
|
||||
// Convert back to linear before applying outset matrix.
|
||||
color = pow(color, vec3(2.4));
|
||||
// Use Timothy Lottes' tonemapping equation to approximate AgX's curve.
|
||||
// Slide 44 of "Advanced Techniques and Optimization of HDR Color Pipelines"
|
||||
// https://gpuopen.com/wp-content/uploads/2016/03/GdcVdrLottes.pdf
|
||||
// color = pow(color, a);
|
||||
// color = color / (pow(color, d) * b + c);
|
||||
// Simplified using hardware-implemented shader operations.
|
||||
// Thanks to Stephen Hill for this optimization tip!
|
||||
color = log2(color);
|
||||
color = exp2(color * a) / (exp2(color * e) * b + c);
|
||||
|
||||
// Apply outset to make the result more chroma-laden and then go back to linear sRGB.
|
||||
color = agx_outset_rec2020_to_srgb_matrix * color;
|
||||
|
|
|
|||
|
|
@ -1278,7 +1278,7 @@ void Environment::_bind_methods() {
|
|||
ADD_GROUP("Tonemap", "tonemap_");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "tonemap_mode", PROPERTY_HINT_ENUM, "Linear,Reinhard,Filmic,ACES,AgX"), "set_tonemapper", "get_tonemapper");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "tonemap_exposure", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_tonemap_exposure", "get_tonemap_exposure");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "tonemap_white", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_tonemap_white", "get_tonemap_white");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "tonemap_white", PROPERTY_HINT_RANGE, "0.01,16,0.01"), "set_tonemap_white", "get_tonemap_white");
|
||||
|
||||
// SSR
|
||||
|
||||
|
|
|
|||
|
|
@ -264,21 +264,14 @@ vec3 tonemap_aces(vec3 color, float white) {
|
|||
return color_tonemapped / white_tonemapped;
|
||||
}
|
||||
|
||||
// Polynomial approximation of EaryChow's AgX sigmoid curve.
|
||||
// x must be within the range [0.0, 1.0]
|
||||
vec3 agx_contrast_approx(vec3 x) {
|
||||
// Generated with Excel trendline
|
||||
// Input data: Generated using python sigmoid with EaryChow's configuration and 57 steps
|
||||
// Additional padding values were added to give correct intersections at 0.0 and 1.0
|
||||
// 6th order, intercept of 0.0 to remove an operation and ensure intersection at 0.0
|
||||
vec3 x2 = x * x;
|
||||
vec3 x4 = x2 * x2;
|
||||
return 0.021 * x + 4.0111 * x2 - 25.682 * x2 * x + 70.359 * x4 - 74.778 * x4 * x + 27.069 * x4 * x2;
|
||||
}
|
||||
|
||||
// This is an approximation and simplification of EaryChow's AgX implementation that is used by Blender.
|
||||
// This is a simplified glsl implementation of EaryChow's AgX that is used by Blender.
|
||||
// Input: unbounded linear Rec. 709
|
||||
// Output: unbounded linear Rec. 709 (Most any value you care about will be within [0.0, 1.0], thus safe to clip.)
|
||||
// This code is based off of the script that generates the AgX_Base_sRGB.cube LUT that Blender uses.
|
||||
// Source: https://github.com/EaryChow/AgX_LUT_Gen/blob/main/AgXBasesRGB.py
|
||||
// Changes: Negative clipping in input color space without "guard rails" and no chroma-angle mixing.
|
||||
// Repository for this code: https://github.com/allenwp/AgX-GLSL-Shaders
|
||||
// Refer to source repository for other matrices if input/output color space ever changes.
|
||||
vec3 tonemap_agx(vec3 color) {
|
||||
// Combined linear sRGB to linear Rec 2020 and Blender AgX inset matrices:
|
||||
const mat3 srgb_to_rec2020_agx_inset_matrix = mat3(
|
||||
|
|
@ -292,11 +285,13 @@ vec3 tonemap_agx(vec3 color) {
|
|||
-0.85585845117807513559, 1.3264510741502356555, -0.23822464068860595117,
|
||||
-0.10886710826831608324, -0.027084020983874825605, 1.402665347143271889);
|
||||
|
||||
// LOG2_MIN = -10.0
|
||||
// LOG2_MAX = +6.5
|
||||
// MIDDLE_GRAY = 0.18
|
||||
const float min_ev = -12.4739311883324; // log2(pow(2, LOG2_MIN) * MIDDLE_GRAY)
|
||||
const float max_ev = 4.02606881166759; // log2(pow(2, LOG2_MAX) * MIDDLE_GRAY)
|
||||
// Terms of Timothy Lottes' tonemapping curve equation:
|
||||
// c and b are calculated based on a and d with AgX mid and max parameters
|
||||
// using the Mathematica notebook in the source AgX-GLSL-Shaders repository.
|
||||
const float a = 1.36989969378897;
|
||||
const float c = 0.3589386656982;
|
||||
const float b = 1.4325264680543;
|
||||
const float e = a * 0.903916850555009; // = a * d
|
||||
|
||||
// Large negative values in one channel and large positive values in other
|
||||
// channels can result in a colour that appears darker and more saturated than
|
||||
|
|
@ -305,28 +300,25 @@ vec3 tonemap_agx(vec3 color) {
|
|||
// This is done before the Rec. 2020 transform to allow the Rec. 2020
|
||||
// transform to be combined with the AgX inset matrix. This results in a loss
|
||||
// of color information that could be correctly interpreted within the
|
||||
// Rec. 2020 color space as positive RGB values, but it is less common for Godot
|
||||
// to provide this function with negative sRGB values and therefore not worth
|
||||
// Rec. 2020 color space as positive RGB values, but is often not worth
|
||||
// the performance cost of an additional matrix multiplication.
|
||||
// A value of 2e-10 intentionally introduces insignificant error to prevent
|
||||
// log2(0.0) after the inset matrix is applied; color will be >= 1e-10 after
|
||||
// the matrix transform.
|
||||
color = max(color, 2e-10);
|
||||
|
||||
// Do AGX in rec2020 to match Blender and then apply inset matrix.
|
||||
// Apply inset matrix.
|
||||
color = srgb_to_rec2020_agx_inset_matrix * color;
|
||||
|
||||
// Log2 space encoding.
|
||||
// Must be clamped because agx_contrast_approx may not work
|
||||
// well with values outside of the range [0.0, 1.0]
|
||||
color = clamp(log2(color), min_ev, max_ev);
|
||||
color = (color - min_ev) / (max_ev - min_ev);
|
||||
|
||||
// Apply sigmoid function approximation.
|
||||
color = agx_contrast_approx(color);
|
||||
|
||||
// Convert back to linear before applying outset matrix.
|
||||
color = pow(color, vec3(2.4));
|
||||
// Use Timothy Lottes' tonemapping equation to approximate AgX's curve.
|
||||
// Slide 44 of "Advanced Techniques and Optimization of HDR Color Pipelines"
|
||||
// https://gpuopen.com/wp-content/uploads/2016/03/GdcVdrLottes.pdf
|
||||
// color = pow(color, a);
|
||||
// color = color / (pow(color, d) * b + c);
|
||||
// Simplified using hardware-implemented shader operations.
|
||||
// Thanks to Stephen Hill for this optimization tip!
|
||||
color = log2(color);
|
||||
color = exp2(color * a) / (exp2(color * e) * b + c);
|
||||
|
||||
// Apply outset to make the result more chroma-laden and then go back to linear sRGB.
|
||||
color = agx_outset_rec2020_to_srgb_matrix * color;
|
||||
|
|
|
|||
Loading…
Reference in New Issue