From 3dc441f268d3e063e54809a09af55956f0502890 Mon Sep 17 00:00:00 2001 From: debian build Date: Thu, 8 Aug 2024 16:00:36 +0000 Subject: [PATCH] Merge custom tonemappers branch --- doc/classes/Environment.xml | 20 +++- doc/classes/RenderingServer.xml | 12 +++ drivers/d3d12/rendering_device_driver_d3d12.h | 2 +- drivers/gles3/shaders/tonemap_inc.glsl | 93 ++++++++++++++++++- scene/3d/lightmap_gi.cpp | 3 +- scene/resources/environment.cpp | 8 +- scene/resources/environment.h | 6 +- servers/movie_writer/movie_writer.cpp | 6 +- .../forward_mobile/render_forward_mobile.cpp | 2 + .../renderer_rd/renderer_scene_render_rd.cpp | 4 +- .../renderer_rd/shaders/effects/tonemap.glsl | 93 ++++++++++++++++++- servers/rendering_server.cpp | 4 + servers/rendering_server.h | 4 + 13 files changed, 242 insertions(+), 15 deletions(-) diff --git a/doc/classes/Environment.xml b/doc/classes/Environment.xml index 73b45cf31cc..4a0ac39f850 100644 --- a/doc/classes/Environment.xml +++ b/doc/classes/Environment.xml @@ -418,14 +418,14 @@ Linear tonemapper operator. Reads the linear data and passes it on unmodified. This can cause bright lighting to look blown out, with noticeable clipping in the output colors. - - Reinhardt tonemapper operator. Performs a variation on rendered pixels' colors by this formula: [code]color = color / (1 + color)[/code]. This avoids clipping bright highlights, but the resulting image can look a bit dull. + + Reinhard tonemapper operator. Performs a variation on rendered pixels' colors by this formula: [code]color = color / (1 + color)[/code]. This avoids clipping bright highlights, but the resulting image can look a bit dull. - Filmic tonemapper operator. This avoids clipping bright highlights, with a resulting image that usually looks more vivid than [constant TONE_MAPPER_REINHARDT]. + Filmic tonemapper operator. This avoids clipping bright highlights, with a resulting image that usually looks more vivid than [constant TONE_MAPPER_REINHARD]. - Use the Academy Color Encoding System tonemapper. ACES is slightly more expensive than other options, but it handles bright lighting in a more realistic fashion by desaturating it as it becomes brighter. ACES typically has a more contrasted output compared to [constant TONE_MAPPER_REINHARDT] and [constant TONE_MAPPER_FILMIC]. + Use the Academy Color Encoding System tonemapper. ACES is slightly more expensive than other options, but it handles bright lighting in a more realistic fashion by desaturating it as it becomes brighter. ACES typically has a more contrasted output compared to [constant TONE_MAPPER_REINHARD] and [constant TONE_MAPPER_FILMIC]. [b]Note:[/b] This tonemapping operator is called "ACES Fitted" in Godot 3.x. @@ -434,6 +434,18 @@ Use the AgX tonemapper with the "punchy" look. AgX is slightly more expensive than other options, but it handles bright lighting in a more realistic fashion by desaturating it as it becomes brighter. The punchy look increases contrast and saturation, bringing its visuals closer to [constant TONE_MAPPER_ACES]. + + Use the Khronos PBR Neutral tonemapper. PBR Neutral handles bright lighting in a more realistic fashion by desaturating it as it becomes brighter. PBR Neutral aims to look similar to [constant TONE_MAPPER_LINEAR] while reducing the clipping of bright highlights. Unlike [constant TONE_MAPPER_ACES], original colors are preserved as much as possible. The whitepoint value is ignored with this tonemapper, as PBR Neutral does not offer a whitepoint adjustment. + + + Use the Uncharted 2 tonemapper (also known as Hable tonemapper). Developed by John Hable for Uncharted 2, this operator provides great contrast and color preservation. It's particularly good at handling bright specular highlights while maintaining rich mid-tones. This tonemapper offers a good balance between realism and visual appeal, often producing more vibrant results than [constant TONE_MAPPER_REINHARD] while avoiding the potential over-saturation of [constant TONE_MAPPER_FILMIC]. + + + Use the Cineon film response curve tonemapper. This method simulates the response of traditional film, providing a cinematic look with rich shadows and controlled highlights. It's particularly effective for preserving details in high-contrast scenes and achieving a classic film aesthetic. Cineon can produce more natural-looking results in some scenarios compared to [constant TONE_MAPPER_FILMIC], especially for scenes with a wide dynamic range. + + + Use Drago's adaptive logarithmic mapping tonemapper (2003). This operator provides good compression of high dynamic range images, preserving details in both dark and bright areas. It adaptively adjusts the logarithmic basis to improve local contrast. Drago's method is particularly effective for scenes with extreme luminance variations and can produce natural-looking results without the need for manual parameter tuning. + Additive glow blending mode. Mostly used for particles, glows (bloom), lens flare, bright sources. diff --git a/doc/classes/RenderingServer.xml b/doc/classes/RenderingServer.xml index f685a1c96a7..3de1019ba50 100644 --- a/doc/classes/RenderingServer.xml +++ b/doc/classes/RenderingServer.xml @@ -5168,6 +5168,18 @@ Use the AgX tonemapper with the "punchy" look. AgX is slightly more expensive than other options, but it handles bright lighting in a more realistic fashion by desaturating it as it becomes brighter. The punchy look increases contrast and saturation, bringing its visuals closer to [constant ENV_TONE_MAPPER_ACES]. + + Use the Khronos PBR Neutral tonemapper. PBR Neutral handles bright lighting in a more realistic fashion by desaturating it as it becomes brighter. PBR Neutral aims to look similar to [constant ENV_TONE_MAPPER_LINEAR] while reducing the clipping of bright highlights. Unlike [constant ENV_TONE_MAPPER_ACES], original colors are preserved as much as possible. The whitepoint value is ignored with this tonemapper, as PBR Neutral does not offer a whitepoint adjustment. + + + Use the Uncharted 2 tonemapper (also known as Hable tonemapper). Developed by John Hable for Uncharted 2, this operator provides excellent contrast and color preservation. It's particularly good at handling bright specular highlights while maintaining rich mid-tones. This tonemapper offers a good balance between realism and visual appeal, often producing more vibrant results than [constant ENV_TONE_MAPPER_REINHARD] while avoiding the potential over-saturation of [constant ENV_TONE_MAPPER_FILMIC]. + + + Use the Cineon film response curve tonemapper. This method simulates the response of traditional film, providing a cinematic look with rich shadows and controlled highlights. It's effective for preserving details in high-contrast scenes and achieving a classic film aesthetic. Cineon can produce more natural-looking results in some scenarios compared to [constant ENV_TONE_MAPPER_FILMIC], especially for scenes with a wide dynamic range. + + + Use Drago's adaptive logarithmic mapping tonemapper (2003). This method compresses high dynamic range images while preserving details across the luminance range. It adaptively adjusts the logarithmic basis to enhance local contrast. Drago's operator is well-suited for scenes with extreme brightness variations, often producing natural-looking results without requiring manual parameter adjustments. + Lowest quality of roughness filter for screen-space reflections. Rough materials will not have blurrier screen-space reflections compared to smooth (non-rough) materials. This is the fastest option. diff --git a/drivers/d3d12/rendering_device_driver_d3d12.h b/drivers/d3d12/rendering_device_driver_d3d12.h index 74e7fd87377..a2404a9115a 100644 --- a/drivers/d3d12/rendering_device_driver_d3d12.h +++ b/drivers/d3d12/rendering_device_driver_d3d12.h @@ -146,7 +146,7 @@ class RenderingDeviceDriverD3D12 : public RenderingDeviceDriver { struct MeshShaderCapabilities { static const uint32_t MAX_THREAD_GROUPS = 63999; // Quoting the DirectX Mesh Shader Spec: "Each of the three thread group counts must be less than 64k" so ok... bool is_supported = false; - }; + }; RenderingContextDriverD3D12 *context_driver = nullptr; RenderingContextDriver::Device context_device; diff --git a/drivers/gles3/shaders/tonemap_inc.glsl b/drivers/gles3/shaders/tonemap_inc.glsl index dd35fe5a0cf..8ec2fac550e 100644 --- a/drivers/gles3/shaders/tonemap_inc.glsl +++ b/drivers/gles3/shaders/tonemap_inc.glsl @@ -80,6 +80,85 @@ vec3 tonemap_aces(vec3 color, float p_white) { return color_tonemapped / p_white_tonemapped; } +// Adapted from https://modelviewer.dev/examples/tone-mapping#commerce +vec3 tonemap_pbr_neutral(vec3 color) { + const float start_compression = 0.8 - 0.04; + const float desaturation = 0.15; + + float x = min(color.r, min(color.g, color.b)); + float offset = x < 0.08 ? x - 6.25 * x * x : 0.04; + color -= offset; + + float peak = max(color.r, max(color.g, color.b)); + if (peak < start_compression) { + return color; + } + + float d = 1.0 - start_compression; + float new_peak = 1.0 - d * d / (peak + d - start_compression); + color *= new_peak / peak; + + float g = 1.0 - 1.0 / (desaturation * (peak - new_peak) + 1.0); + return mix(color, vec3(1.0, 1.0, 1.0), g); +} + +// "Hable Tone Mapping" a.k.a Uncharted 2 tonemapping. +// source: https://64.github.io/tonemapping/#uncharted-2 +vec3 hable_tonemap_partial(vec3 x) { + const float A = 0.15f; + const float B = 0.50f; + const float C = 0.10f; + const float D = 0.20f; + const float E = 0.02f; + const float F = 0.30f; + return ((x * (A * x + C * B) + D * E) / (x * (A * x + B) + D * F)) - E / F; +} + +vec3 tonemap_hable(vec3 color, float white) { + const float EXPOSURE_BIAS = 2.0f; + vec3 curr = hable_tonemap_partial(color * EXPOSURE_BIAS); + + vec3 W = vec3(11.2f); + float white_padding = white; + if (white >= 1.0) { + white_padding = white + 1.0; + } + vec3 white_scale = vec3(white_padding) / hable_tonemap_partial(W); + return curr * white_scale; +} + +// Optimised cineon tonemapping. +// Adapted from Three.js (MIT) +vec3 tonemap_cineon(vec3 color, float white) { + color *= white; + color = max(vec3(0.0), color - 0.004); + return pow( + (color * (6.2 * color + 0.5)) / + (color * (6.2 * color + 1.7) + 0.06), + vec3(2.2) + ); +} + +float luminance_drago(float L, float b) { + const float LMax = 1.0; + float Ld = b / (log(LMax + 1.0) / log(10.0)); + Ld *= log(L + 1.0) / log(2.0 + 8.0 * pow((L / LMax), log(b) / log(0.5))); + return Ld; +} + +// Based on the paper: "Adaptive Logarithmic Mapping For Displaying High Contrast Scenes" +// https://resources.mpi-inf.mpg.de/tmo/logmap/logmap.pdf +vec3 tonemap_drago(vec3 color, float white) { + const float BIAS = 0.85; + + float luminance = dot(color, vec3(0.2126, 0.7152, 0.0722)); + float Ld = luminance_drago(luminance, BIAS); + color = color * (Ld / luminance); + color *= white; + return clamp(color, 0.0, 1.0); +} + +>>>>>>> origin/tonemappers // Mean error^2: 3.6705141e-06 vec3 agx_default_contrast_approx(vec3 x) { vec3 x2 = x * x; @@ -157,6 +236,10 @@ vec3 tonemap_agx(vec3 color, float white, bool punchy) { #define TONEMAPPER_ACES 3 #define TONEMAPPER_AGX 4 #define TONEMAPPER_AGX_PUNCHY 5 +#define TONEMAPPER_PBR_NEUTRAL 6 +#define TONEMAPPER_HABLE 7 +#define TONEMAPPER_CINEON 8 +#define TONEMAPPER_DRAGO 9 vec3 apply_tonemapping(vec3 color, float p_white) { // inputs are LINEAR, always outputs clamped [0;1] color // Ensure color values passed to tonemappers are positive. @@ -171,8 +254,16 @@ vec3 apply_tonemapping(vec3 color, float p_white) { // inputs are LINEAR, always return tonemap_aces(max(vec3(0.0f), color), p_white); } else if (tonemapper == TONEMAPPER_AGX) { return tonemap_agx(max(vec3(0.0f), color), p_white, false); - } else { // TONEMAPPER_AGX_PUNCHY + } else if (tonemapper == TONEMAPPER_AGX_PUNCHY){ return tonemap_agx(max(vec3(0.0f), color), p_white, true); + } else if (tonemapper == TONEMAPPER_PBR_NEUTRAL) { + return tonemap_pbr_neutral(max(vec3(0.0f), color)); + } else if (tonemapper == TONEMAPPER_HABLE) { + return tonemap_hable(max(vec3(0.0f), color), p_white); + } else if (tonemapper == TONEMAPPER_CINEON) { + return tonemap_cineon(max(vec3(0.0f), color), white); + } else { // TONEMAPPER_DRAGO + return tonemap_drago(max(vec3(0.0f), color), white); } } diff --git a/scene/3d/lightmap_gi.cpp b/scene/3d/lightmap_gi.cpp index 491d657edd9..863c0b28fd2 100644 --- a/scene/3d/lightmap_gi.cpp +++ b/scene/3d/lightmap_gi.cpp @@ -1163,10 +1163,11 @@ LightmapGI::BakeError LightmapGI::bake(Node *p_from_node, String p_image_data_pa } } - Lightmapper::BakeError lightmapper->bake( + Lightmapper::BakeError bake_err = lightmapper->bake( Lightmapper::BakeQuality(effective_bake_quality), use_denoiser, denoiser_strength, + denoiser_range, effective_bounces, bounce_indirect_energy, bias, diff --git a/scene/resources/environment.cpp b/scene/resources/environment.cpp index 2feb7f26dd7..57d33ea59ce 100644 --- a/scene/resources/environment.cpp +++ b/scene/resources/environment.cpp @@ -1322,7 +1322,7 @@ void Environment::_bind_methods() { ClassDB::bind_method(D_METHOD("get_tonemap_white"), &Environment::get_tonemap_white); ADD_GROUP("Tonemap", "tonemap_"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "tonemap_mode", PROPERTY_HINT_ENUM, "Linear,Reinhard,Filmic,ACES,AgX,AgX Punchy"), "set_tonemapper", "get_tonemapper"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "tonemap_mode", PROPERTY_HINT_ENUM, "Linear,Reinhard,Filmic,ACES,AgX,AgX Punchy,PBR Neutral,Hable Filmic,Cineon,Drago"), "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"); @@ -1642,11 +1642,15 @@ void Environment::_bind_methods() { BIND_ENUM_CONSTANT(REFLECTION_SOURCE_SKY); BIND_ENUM_CONSTANT(TONE_MAPPER_LINEAR); - BIND_ENUM_CONSTANT(TONE_MAPPER_REINHARDT); + BIND_ENUM_CONSTANT(TONE_MAPPER_REINHARD); BIND_ENUM_CONSTANT(TONE_MAPPER_FILMIC); BIND_ENUM_CONSTANT(TONE_MAPPER_ACES); BIND_ENUM_CONSTANT(TONE_MAPPER_AGX); BIND_ENUM_CONSTANT(TONE_MAPPER_AGX_PUNCHY); + BIND_ENUM_CONSTANT(TONE_MAPPER_PBR_NEUTRAL); + BIND_ENUM_CONSTANT(TONE_MAPPER_HABLE); + BIND_ENUM_CONSTANT(TONE_MAPPER_CINEON); + BIND_ENUM_CONSTANT(TONE_MAPPER_DRAGO); BIND_ENUM_CONSTANT(GLOW_BLEND_MODE_ADDITIVE); BIND_ENUM_CONSTANT(GLOW_BLEND_MODE_SCREEN); diff --git a/scene/resources/environment.h b/scene/resources/environment.h index 8955d4c1b4c..cbae1114c1b 100644 --- a/scene/resources/environment.h +++ b/scene/resources/environment.h @@ -64,11 +64,15 @@ class Environment : public Resource { enum ToneMapper { TONE_MAPPER_LINEAR, - TONE_MAPPER_REINHARDT, + TONE_MAPPER_REINHARD, TONE_MAPPER_FILMIC, TONE_MAPPER_ACES, TONE_MAPPER_AGX, TONE_MAPPER_AGX_PUNCHY, + TONE_MAPPER_PBR_NEUTRAL, + TONE_MAPPER_HABLE, + TONE_MAPPER_CINEON, + TONE_MAPPER_DRAGO, }; enum DynamicGICascadeFormat { diff --git a/servers/movie_writer/movie_writer.cpp b/servers/movie_writer/movie_writer.cpp index 28688ba53d7..c401e49c4fb 100644 --- a/servers/movie_writer/movie_writer.cpp +++ b/servers/movie_writer/movie_writer.cpp @@ -191,20 +191,22 @@ void MovieWriter::add_frame() { #ifdef DEBUG_ENABLED DisplayServer::get_singleton()->window_set_title( vformat( - "MovieWriter: Frame %d (time: %s) - %s | real time: %s (DEBUG)", + "MovieWriter: Frame %d (time: %s) - %s (frames saved: %s) | real time: %s (DEBUG)", Engine::get_singleton()->get_frames_drawn(), movie_time, project_name, + frame_to_save, real_time ) ); #else DisplayServer::get_singleton()->window_set_title( vformat( - "MovieWriter: Frame %d (time: %s) - %s | real time: %s", + "MovieWriter: Frame %d (time: %s) - %s (frames saved: %s) | real time: %s", Engine::get_singleton()->get_frames_drawn(), movie_time, project_name, + frame_to_save, real_time ) ); diff --git a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp index f969bd2c95b..911502a423e 100644 --- a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp +++ b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp @@ -2816,6 +2816,8 @@ RenderForwardMobile::RenderForwardMobile() { // defines += "\n#define HDDAGI_OCT_SIZE " + itos(gi.hddagi_get_lightprobe_octahedron_size()) + "\n"; defines += "\n#define MAX_DIRECTIONAL_LIGHT_DATA_STRUCTS " + itos(MAX_DIRECTIONAL_LIGHTS) + "\n"; } + // defines += "\n#define HDDAGI_OCT_SIZE " + itos(gi.hddagi_get_lightprobe_octahedron_size()) + "\n"; + defines += "\n#define MAX_DIRECTIONAL_LIGHT_DATA_STRUCTS " + itos(MAX_DIRECTIONAL_LIGHTS) + "\n"; { //lightmaps diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp index fcc28e00a09..5e917350ead 100644 --- a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp @@ -797,7 +797,7 @@ bool RendererSceneRenderRD::_debug_draw_can_use_effects(RS::ViewportDebugDraw p_ case RS::VIEWPORT_DEBUG_DRAW_NORMAL_BUFFER: case RS::VIEWPORT_DEBUG_DRAW_SSAO: case RS::VIEWPORT_DEBUG_DRAW_SSIL: - case RS::VIEWPORT_DEBUG_DRAW_SDFGI: + case RS::VIEWPORT_DEBUG_DRAW_HDDAGI: case RS::VIEWPORT_DEBUG_DRAW_GI_BUFFER: case RS::VIEWPORT_DEBUG_DRAW_OCCLUDERS: can_use_effects = true; @@ -808,7 +808,7 @@ bool RendererSceneRenderRD::_debug_draw_can_use_effects(RS::ViewportDebugDraw p_ case RS::VIEWPORT_DEBUG_DRAW_VOXEL_GI_EMISSION: case RS::VIEWPORT_DEBUG_DRAW_SCENE_LUMINANCE: case RS::VIEWPORT_DEBUG_DRAW_PSSM_SPLITS: - case RS::VIEWPORT_DEBUG_DRAW_SDFGI_PROBES: + case RS::VIEWPORT_DEBUG_DRAW_HDDAGI_PROBES: case RS::VIEWPORT_DEBUG_DRAW_DISABLE_LOD: can_use_effects = true; break; diff --git a/servers/rendering/renderer_rd/shaders/effects/tonemap.glsl b/servers/rendering/renderer_rd/shaders/effects/tonemap.glsl index f3ff288c540..bd2b5b79cef 100644 --- a/servers/rendering/renderer_rd/shaders/effects/tonemap.glsl +++ b/servers/rendering/renderer_rd/shaders/effects/tonemap.glsl @@ -331,6 +331,85 @@ vec3 tonemap_agx(vec3 color, float white, bool punchy) { return color; } +// Adapted from https://modelviewer.dev/examples/tone-mapping#commerce +vec3 tonemap_pbr_neutral(vec3 color) { + const float start_compression = 0.8 - 0.04; + const float desaturation = 0.15; + + float x = min(color.r, min(color.g, color.b)); + float offset = x < 0.08 ? x - 6.25 * x * x : 0.04; + color -= offset; + + float peak = max(color.r, max(color.g, color.b)); + if (peak < start_compression) { + return color; + } + + float d = 1.0 - start_compression; + float new_peak = 1.0 - d * d / (peak + d - start_compression); + color *= new_peak / peak; + + float g = 1.0 - 1.0 / (desaturation * (peak - new_peak) + 1.0); + return mix(color, vec3(1.0, 1.0, 1.0), g); +} + +// "Hable Tone Mapping" a.k.a Uncharted 2 tonemapping. +// source: https://64.github.io/tonemapping/#uncharted-2 +vec3 hable_tonemap_partial(vec3 x) { + const float A = 0.15f; + const float B = 0.50f; + const float C = 0.10f; + const float D = 0.20f; + const float E = 0.02f; + const float F = 0.30f; + return ((x * (A * x + C * B) + D * E) / (x * (A * x + B) + D * F)) - E / F; +} + +vec3 tonemap_hable(vec3 color, float white) { + const float EXPOSURE_BIAS = 2.0f; + vec3 curr = hable_tonemap_partial(color * EXPOSURE_BIAS); + + vec3 W = vec3(11.2f); + float white_padding = white; + if (white >= 1.0) { + white_padding = white + 1.0; + } + vec3 white_scale = vec3(white_padding) / hable_tonemap_partial(W); + return curr * white_scale; +} + +// Optimised cineon tonemapping. +// Adapted from Three.js (MIT) +vec3 tonemap_cineon(vec3 color, float white) { + color *= white; + color = max(vec3(0.0), color - 0.004); + return pow( + (color * (6.2 * color + 0.5)) / + (color * (6.2 * color + 1.7) + 0.06), + vec3(2.2) + ); +} + +float luminance_drago(float L, float b) { + const float LMax = 1.0; + float Ld = b / (log(LMax + 1.0) / log(10.0)); + Ld *= log(L + 1.0) / log(2.0 + 8.0 * pow((L / LMax), log(b) / log(0.5))); + return Ld; +} + +// Based on the paper: "Adaptive Logarithmic Mapping For Displaying High Contrast Scenes" +// https://resources.mpi-inf.mpg.de/tmo/logmap/logmap.pdf +vec3 tonemap_drago(vec3 color, float white) { + const float BIAS = 0.85; + + float luminance = dot(color, vec3(0.2126, 0.7152, 0.0722)); + float Ld = luminance_drago(luminance, BIAS); + color = color * (Ld / luminance); + color *= white; + return clamp(color, 0.0, 1.0); +>>>>>>> origin/tonemappers +} + vec3 linear_to_srgb(vec3 color) { //if going to srgb, clamp from 0 to 1. color = clamp(color, vec3(0.0), vec3(1.0)); @@ -344,6 +423,10 @@ vec3 linear_to_srgb(vec3 color) { #define TONEMAPPER_ACES 3 #define TONEMAPPER_AGX 4 #define TONEMAPPER_AGX_PUNCHY 5 +#define TONEMAPPER_PBR_NEUTRAL 6 +#define TONEMAPPER_HABLE 7 +#define TONEMAPPER_CINEON 8 +#define TONEMAPPER_DRAGO 9 vec3 apply_tonemapping(vec3 color, float white) { // inputs are LINEAR, always outputs clamped [0;1] color // Ensure color values passed to tonemappers are positive. @@ -358,8 +441,16 @@ vec3 apply_tonemapping(vec3 color, float white) { // inputs are LINEAR, always o return tonemap_aces(max(vec3(0.0f), color), white); } else if (params.tonemapper == TONEMAPPER_AGX) { return tonemap_agx(max(vec3(0.0f), color), white, false); - } else { // TONEMAPPER_AGX_PUNCHY + } else if (params.tonemapper == TONEMAPPER_AGX_PUNCHY) { return tonemap_agx(max(vec3(0.0f), color), white, true); + } else if (params.tonemapper == TONEMAPPER_PBR_NEUTRAL) { + return tonemap_pbr_neutral(max(vec3(0.0f), color)); + } else if (params.tonemapper == TONEMAPPER_HABLE) { + return tonemap_hable(max(vec3(0.0f), color), white); + } else if (params.tonemapper == TONEMAPPER_CINEON) { + return tonemap_cineon(max(vec3(0.0f), color), white); + } else { // TONEMAPPER_DRAGO + return tonemap_drago(max(vec3(0.0f), color), white); } } diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp index 6a27025b8bf..175c309d9ce 100644 --- a/servers/rendering_server.cpp +++ b/servers/rendering_server.cpp @@ -3040,6 +3040,10 @@ void RenderingServer::_bind_methods() { BIND_ENUM_CONSTANT(ENV_TONE_MAPPER_ACES); BIND_ENUM_CONSTANT(ENV_TONE_MAPPER_AGX); BIND_ENUM_CONSTANT(ENV_TONE_MAPPER_AGX_PUNCHY); + BIND_ENUM_CONSTANT(ENV_TONE_MAPPER_PBR_NEUTRAL); + BIND_ENUM_CONSTANT(ENV_TONE_MAPPER_HABLE); + BIND_ENUM_CONSTANT(ENV_TONE_MAPPER_CINEON); + BIND_ENUM_CONSTANT(ENV_TONE_MAPPER_DRAGO); BIND_ENUM_CONSTANT(ENV_SSR_ROUGHNESS_QUALITY_DISABLED); BIND_ENUM_CONSTANT(ENV_SSR_ROUGHNESS_QUALITY_LOW); diff --git a/servers/rendering_server.h b/servers/rendering_server.h index a693961707b..d488d54aefd 100644 --- a/servers/rendering_server.h +++ b/servers/rendering_server.h @@ -1169,6 +1169,10 @@ class RenderingServer : public Object { ENV_TONE_MAPPER_ACES, ENV_TONE_MAPPER_AGX, ENV_TONE_MAPPER_AGX_PUNCHY, + ENV_TONE_MAPPER_PBR_NEUTRAL, + ENV_TONE_MAPPER_HABLE, + ENV_TONE_MAPPER_CINEON, + ENV_TONE_MAPPER_DRAGO, }; virtual void environment_set_tonemap(RID p_env, EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white) = 0;