You've already forked godot
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:
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user