1
0
mirror of https://github.com/godotengine/godot.git synced 2025-11-04 12:00:25 +00:00

Blend Environment glow before tonemapping and change default blend mode to screen.

Additionally, change the minimum `tonemap_white` parameter to `1.0`; users can increase `tonemap_exposure` for a similar effect to decreasing `tonemap_white` below `1.0`.

Co-authored-by: Hei <40064911+Lielay9@users.noreply.github.com>
Co-authored-by: Hugo Locurcio <hugo.locurcio@hugo.pro>
This commit is contained in:
Allen Pestaluky
2025-09-17 17:09:46 -04:00
parent 9a5d6d1049
commit cafc012b05
11 changed files with 150 additions and 80 deletions

View File

@@ -87,7 +87,7 @@ void PostEffects::_draw_screen_triangle() {
glBindVertexArray(0);
}
void PostEffects::post_copy(GLuint p_dest_framebuffer, Size2i p_dest_size, GLuint p_source_color, Size2i p_source_size, float p_luminance_multiplier, const Glow::GLOWLEVEL *p_glow_buffers, float p_glow_intensity, uint32_t p_view, bool p_use_multiview, uint64_t p_spec_constants) {
void PostEffects::post_copy(GLuint p_dest_framebuffer, Size2i p_dest_size, GLuint p_source_color, Size2i p_source_size, float p_luminance_multiplier, const Glow::GLOWLEVEL *p_glow_buffers, float p_glow_intensity, float p_srgb_white, uint32_t p_view, bool p_use_multiview, uint64_t p_spec_constants) {
glDisable(GL_DEPTH_TEST);
glDepthMask(GL_FALSE);
glDisable(GL_BLEND);
@@ -124,6 +124,7 @@ void PostEffects::post_copy(GLuint p_dest_framebuffer, Size2i p_dest_size, GLuin
post.shader.version_set_uniform(PostShaderGLES3::PIXEL_SIZE, 1.0 / p_source_size.x, 1.0 / p_source_size.y, post.shader_version, mode, flags);
post.shader.version_set_uniform(PostShaderGLES3::GLOW_INTENSITY, p_glow_intensity, post.shader_version, mode, flags);
post.shader.version_set_uniform(PostShaderGLES3::SRGB_WHITE, p_srgb_white, post.shader_version, mode, flags);
}
post.shader.version_set_uniform(PostShaderGLES3::VIEW, float(p_view), post.shader_version, mode, flags);

View File

@@ -58,7 +58,7 @@ public:
PostEffects();
~PostEffects();
void post_copy(GLuint p_dest_framebuffer, Size2i p_dest_size, GLuint p_source_color, Size2i p_source_size, float p_luminance_multiplier, const Glow::GLOWLEVEL *p_glow_buffers, float p_glow_intensity, uint32_t p_view = 0, bool p_use_multiview = false, uint64_t p_spec_constants = 0);
void post_copy(GLuint p_dest_framebuffer, Size2i p_dest_size, GLuint p_source_color, Size2i p_source_size, float p_luminance_multiplier, const Glow::GLOWLEVEL *p_glow_buffers, float p_glow_intensity, float p_srgb_white, uint32_t p_view = 0, bool p_use_multiview = false, uint64_t p_spec_constants = 0);
};
} //namespace GLES3

View File

@@ -2814,6 +2814,7 @@ void RasterizerSceneGLES3::_render_post_processing(const RenderDataGLES3 *p_rend
float glow_hdr_bleed_threshold = 1.0;
float glow_hdr_bleed_scale = 2.0;
float glow_hdr_luminance_cap = 12.0;
float srgb_white = 1.0;
if (p_render_data->environment.is_valid()) {
glow_enabled = environment_get_glow_enabled(p_render_data->environment);
glow_intensity = environment_get_glow_intensity(p_render_data->environment);
@@ -2821,9 +2822,13 @@ void RasterizerSceneGLES3::_render_post_processing(const RenderDataGLES3 *p_rend
glow_hdr_bleed_threshold = environment_get_glow_hdr_bleed_threshold(p_render_data->environment);
glow_hdr_bleed_scale = environment_get_glow_hdr_bleed_scale(p_render_data->environment);
glow_hdr_luminance_cap = environment_get_glow_hdr_luminance_cap(p_render_data->environment);
srgb_white = environment_get_white(p_render_data->environment);
}
if (glow_enabled) {
// Only glow requires srgb_white to be calculated.
srgb_white = 1.055 * Math::pow(srgb_white, 1.0f / 2.4f) - 0.055;
rb->check_glow_buffers();
}
@@ -2890,7 +2895,7 @@ void RasterizerSceneGLES3::_render_post_processing(const RenderDataGLES3 *p_rend
}
// Copy color buffer
post_effects->post_copy(fbo_rt, target_size, color, internal_size, p_render_data->luminance_multiplier, glow_buffers, glow_intensity, 0, false, bcs_spec_constants);
post_effects->post_copy(fbo_rt, target_size, color, internal_size, p_render_data->luminance_multiplier, glow_buffers, glow_intensity, srgb_white, 0, false, bcs_spec_constants);
// Copy depth buffer
glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo_int);
@@ -2958,7 +2963,7 @@ void RasterizerSceneGLES3::_render_post_processing(const RenderDataGLES3 *p_rend
glBindFramebuffer(GL_FRAMEBUFFER, fbos[2]);
glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, write_color, 0, v);
post_effects->post_copy(fbos[2], target_size, source_color, internal_size, p_render_data->luminance_multiplier, glow_buffers, glow_intensity, v, true, bcs_spec_constants);
post_effects->post_copy(fbos[2], target_size, source_color, internal_size, p_render_data->luminance_multiplier, glow_buffers, glow_intensity, srgb_white, v, true, bcs_spec_constants);
}
// Copy depth

View File

@@ -45,6 +45,7 @@ uniform float luminance_multiplier;
uniform sampler2D glow_color; // texunit:1
uniform vec2 pixel_size;
uniform float glow_intensity;
uniform float srgb_white;
vec4 get_glow_color(vec2 uv) {
vec2 half_pixel = pixel_size * 0.5;
@@ -58,6 +59,10 @@ vec4 get_glow_color(vec2 uv) {
color += textureLod(glow_color, uv + vec2(0.0, -half_pixel.y * 2.0), 0.0);
color += textureLod(glow_color, uv + vec2(-half_pixel.x, -half_pixel.y), 0.0) * 2.0;
#ifdef USE_LUMINANCE_MULTIPLIER
color = color / luminance_multiplier;
#endif
return color / 12.0;
}
#endif // USE_GLOW
@@ -102,18 +107,38 @@ void main() {
vec4 color = texture(source_color, uv_interp);
#endif
#ifdef USE_GLOW
vec4 glow = get_glow_color(uv_interp) * glow_intensity;
// Just use softlight...
glow.rgb = clamp(glow.rgb, vec3(0.0f), vec3(1.0f));
color.rgb = max((color.rgb + glow.rgb) - (color.rgb * glow.rgb), vec3(0.0));
#endif // USE_GLOW
#ifdef USE_LUMINANCE_MULTIPLIER
color = color / luminance_multiplier;
#endif
#ifdef USE_GLOW
// Glow blending is performed before srgb_to_linear because
// the glow texture was created from a nonlinear sRGB-encoded
// scene, so it only makes sense to add this glow to an equally
// nonlinear sRGB-encoded scene.
vec4 glow = get_glow_color(uv_interp) * glow_intensity;
// Glow always uses the screen blend mode in the Compatibility renderer:
// Glow cannot be above 1.0 after normalizing and should be non-negative
// to produce expected results. It is possible that glow can be negative
// if negative lights were used in the scene.
// We clamp to srgb_white because glow will be normalized to this range.
// Note: srgb_white cannot be smaller than the maximum output value (1.0).
glow.rgb = clamp(glow.rgb, 0.0, srgb_white);
// Normalize to srgb_white range.
//glow.rgb /= srgb_white;
//color.rgb /= srgb_white;
//color.rgb = (color.rgb + glow.rgb) - (color.rgb * glow.rgb);
// Expand back to original range.
//color.rgb *= srgb_white;
// The following is a mathematically simplified version of the above.
color.rgb = color.rgb + glow.rgb - (color.rgb * glow.rgb / srgb_white);
#endif // USE_GLOW
color.rgb = srgb_to_linear(color.rgb);
color.rgb = apply_tonemapping(color.rgb, white);
color.rgb = linear_to_srgb(color.rgb);