Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add high quality glow mode (3.x) #51491

Merged
merged 1 commit into from
Oct 8, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions doc/classes/Environment.xml
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,9 @@
<member name="glow_hdr_threshold" type="float" setter="set_glow_hdr_bleed_threshold" getter="get_glow_hdr_bleed_threshold" default="1.0">
The lower threshold of the HDR glow. When using the GLES2 renderer (which doesn't support HDR), this needs to be below [code]1.0[/code] for glow to be visible. A value of [code]0.9[/code] works well in this case.
</member>
<member name="glow_high_quality" type="bool" setter="set_glow_high_quality" getter="is_glow_high_quality_enabled" default="false">
Takes more samples during downsample pass of glow. This ensures that single pixels are captured by glow which makes the glow look smoother and more stable during movement. However, it is very expensive and makes the glow post process take twice as long.
</member>
<member name="glow_intensity" type="float" setter="set_glow_intensity" getter="get_glow_intensity" default="0.8">
The glow intensity. When using the GLES2 renderer, this should be increased to 1.5 to compensate for the lack of HDR rendering.
</member>
Expand Down
1 change: 1 addition & 0 deletions doc/classes/VisualServer.xml
Original file line number Diff line number Diff line change
Expand Up @@ -861,6 +861,7 @@
<argument index="8" name="hdr_bleed_scale" type="float" />
<argument index="9" name="hdr_luminance_cap" type="float" />
<argument index="10" name="bicubic_upscale" type="bool" />
<argument index="11" name="high_quality" type="bool" />
<description>
Sets the variables to be used with the "glow" post-process effect. See [Environment] for more details.
</description>
Expand Down
2 changes: 1 addition & 1 deletion drivers/dummy/rasterizer_dummy.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ class RasterizerSceneDummy : public RasterizerScene {

void environment_set_dof_blur_near(RID p_env, bool p_enable, float p_distance, float p_transition, float p_far_amount, VS::EnvironmentDOFBlurQuality p_quality) {}
void environment_set_dof_blur_far(RID p_env, bool p_enable, float p_distance, float p_transition, float p_far_amount, VS::EnvironmentDOFBlurQuality p_quality) {}
void environment_set_glow(RID p_env, bool p_enable, int p_level_flags, float p_intensity, float p_strength, float p_bloom_threshold, VS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap, bool p_bicubic_upscale) {}
void environment_set_glow(RID p_env, bool p_enable, int p_level_flags, float p_intensity, float p_strength, float p_bloom_threshold, VS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap, bool p_bicubic_upscale, bool p_high_quality) {}

void environment_set_fog(RID p_env, bool p_enable, float p_begin, float p_end, RID p_gradient_texture) {}

Expand Down
4 changes: 3 additions & 1 deletion drivers/gles2/rasterizer_scene_gles2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -772,7 +772,7 @@ void RasterizerSceneGLES2::environment_set_dof_blur_near(RID p_env, bool p_enabl
env->dof_blur_near_quality = p_quality;
}

void RasterizerSceneGLES2::environment_set_glow(RID p_env, bool p_enable, int p_level_flags, float p_intensity, float p_strength, float p_bloom_threshold, VS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap, bool p_bicubic_upscale) {
void RasterizerSceneGLES2::environment_set_glow(RID p_env, bool p_enable, int p_level_flags, float p_intensity, float p_strength, float p_bloom_threshold, VS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap, bool p_bicubic_upscale, bool p_high_quality) {
Environment *env = environment_owner.getornull(p_env);
ERR_FAIL_COND(!env);

Expand All @@ -786,6 +786,7 @@ void RasterizerSceneGLES2::environment_set_glow(RID p_env, bool p_enable, int p_
env->glow_hdr_bleed_scale = p_hdr_bleed_scale;
env->glow_hdr_luminance_cap = p_hdr_luminance_cap;
env->glow_bicubic_upscale = p_bicubic_upscale;
env->glow_high_quality = p_high_quality;
}

void RasterizerSceneGLES2::environment_set_fog(RID p_env, bool p_enable, float p_begin, float p_end, RID p_gradient_texture) {
Expand Down Expand Up @@ -3187,6 +3188,7 @@ void RasterizerSceneGLES2::_post_process(Environment *env, const CameraMatrix &p
}

state.effect_blur_shader.set_conditional(EffectBlurShaderGLES2::GLOW_GAUSSIAN_HORIZONTAL, true);
state.effect_blur_shader.set_conditional(EffectBlurShaderGLES2::USE_GLOW_HIGH_QUALITY, env->glow_high_quality);
state.effect_blur_shader.bind();
state.effect_blur_shader.set_uniform(EffectBlurShaderGLES2::PIXEL_SIZE, Vector2(1.0 / vp_w, 1.0 / vp_h));
state.effect_blur_shader.set_uniform(EffectBlurShaderGLES2::LOD, storage->frame.current_rt->mip_maps[0].color ? float(i) : 0.0);
Expand Down
4 changes: 3 additions & 1 deletion drivers/gles2/rasterizer_scene_gles2.h
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,7 @@ class RasterizerSceneGLES2 : public RasterizerScene {
float glow_hdr_bleed_scale;
float glow_hdr_luminance_cap;
bool glow_bicubic_upscale;
bool glow_high_quality;

bool dof_blur_far_enabled;
float dof_blur_far_distance;
Expand Down Expand Up @@ -430,6 +431,7 @@ class RasterizerSceneGLES2 : public RasterizerScene {
glow_hdr_bleed_scale(2.0),
glow_hdr_luminance_cap(12.0),
glow_bicubic_upscale(false),
glow_high_quality(false),
dof_blur_far_enabled(false),
dof_blur_far_distance(10),
dof_blur_far_transition(5),
Expand Down Expand Up @@ -478,7 +480,7 @@ class RasterizerSceneGLES2 : public RasterizerScene {
virtual void environment_set_dof_blur_near(RID p_env, bool p_enable, float p_distance, float p_transition, float p_amount, VS::EnvironmentDOFBlurQuality p_quality);
virtual void environment_set_dof_blur_far(RID p_env, bool p_enable, float p_distance, float p_transition, float p_amount, VS::EnvironmentDOFBlurQuality p_quality);

virtual void environment_set_glow(RID p_env, bool p_enable, int p_level_flags, float p_intensity, float p_strength, float p_bloom_threshold, VS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap, bool p_bicubic_upscale);
virtual void environment_set_glow(RID p_env, bool p_enable, int p_level_flags, float p_intensity, float p_strength, float p_bloom_threshold, VS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap, bool p_bicubic_upscale, bool p_high_quality);
virtual void environment_set_fog(RID p_env, bool p_enable, float p_begin, float p_end, RID p_gradient_texture);

virtual void environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_fade_in, float p_fade_out, float p_depth_tolerance, bool p_roughness);
Expand Down
29 changes: 28 additions & 1 deletion drivers/gles2/shaders/effect_blur.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -129,16 +129,43 @@ void main() {
#ifdef GLOW_GAUSSIAN_HORIZONTAL
vec2 pix_size = pixel_size;
pix_size *= 0.5; //reading from larger buffer, so use more samples

#ifdef USE_GLOW_HIGH_QUALITY
// Sample from two lines to capture single-pixel features.
// This is significantly slower, but looks better and is more stable for moving objects.
vec4 color = texture2DLod(source_color, uv_interp + vec2(0.0, 0.0) * pix_size, lod) * 0.152781;
color += texture2DLod(source_color, uv_interp + vec2(1.0, 0.0) * pix_size, lod) * 0.144599;
color += texture2DLod(source_color, uv_interp + vec2(2.0, 0.0) * pix_size, lod) * 0.122589;
color += texture2DLod(source_color, uv_interp + vec2(3.0, 0.0) * pix_size, lod) * 0.093095;
color += texture2DLod(source_color, uv_interp + vec2(4.0, 0.0) * pix_size, lod) * 0.063327;
color += texture2DLod(source_color, uv_interp + vec2(-1.0, 0.0) * pix_size, lod) * 0.144599;
color += texture2DLod(source_color, uv_interp + vec2(-2.0, 0.0) * pix_size, lod) * 0.122589;
color += texture2DLod(source_color, uv_interp + vec2(-3.0, 0.0) * pix_size, lod) * 0.093095;
color += texture2DLod(source_color, uv_interp + vec2(-4.0, 0.0) * pix_size, lod) * 0.063327;

color += texture2DLod(source_color, uv_interp + vec2(0.0, 1.0) * pix_size, lod) * 0.152781;
color += texture2DLod(source_color, uv_interp + vec2(1.0, 1.0) * pix_size, lod) * 0.144599;
color += texture2DLod(source_color, uv_interp + vec2(2.0, 1.0) * pix_size, lod) * 0.122589;
color += texture2DLod(source_color, uv_interp + vec2(3.0, 1.0) * pix_size, lod) * 0.093095;
color += texture2DLod(source_color, uv_interp + vec2(4.0, 1.0) * pix_size, lod) * 0.063327;
color += texture2DLod(source_color, uv_interp + vec2(-1.0, 1.0) * pix_size, lod) * 0.144599;
color += texture2DLod(source_color, uv_interp + vec2(-2.0, 1.0) * pix_size, lod) * 0.122589;
color += texture2DLod(source_color, uv_interp + vec2(-3.0, 1.0) * pix_size, lod) * 0.093095;
color += texture2DLod(source_color, uv_interp + vec2(-4.0, 1.0) * pix_size, lod) * 0.063327;
color *= 0.5;
#else
vec4 color = texture2DLod(source_color, uv_interp + vec2(0.0, 0.0) * pix_size, lod) * 0.174938;
color += texture2DLod(source_color, uv_interp + vec2(1.0, 0.0) * pix_size, lod) * 0.165569;
color += texture2DLod(source_color, uv_interp + vec2(2.0, 0.0) * pix_size, lod) * 0.140367;
color += texture2DLod(source_color, uv_interp + vec2(3.0, 0.0) * pix_size, lod) * 0.106595;
color += texture2DLod(source_color, uv_interp + vec2(-1.0, 0.0) * pix_size, lod) * 0.165569;
color += texture2DLod(source_color, uv_interp + vec2(-2.0, 0.0) * pix_size, lod) * 0.140367;
color += texture2DLod(source_color, uv_interp + vec2(-3.0, 0.0) * pix_size, lod) * 0.106595;
#endif //USE_GLOW_HIGH_QUALITY

color *= glow_strength;
gl_FragColor = color;
#endif
#endif //GLOW_GAUSSIAN_HORIZONTAL

#ifdef GLOW_GAUSSIAN_VERTICAL
vec4 color = texture2DLod(source_color, uv_interp + vec2(0.0, 0.0) * pixel_size, lod) * 0.288713;
Expand Down
4 changes: 3 additions & 1 deletion drivers/gles3/rasterizer_scene_gles3.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -838,7 +838,7 @@ void RasterizerSceneGLES3::environment_set_dof_blur_near(RID p_env, bool p_enabl
env->dof_blur_near_quality = p_quality;
}

void RasterizerSceneGLES3::environment_set_glow(RID p_env, bool p_enable, int p_level_flags, float p_intensity, float p_strength, float p_bloom_threshold, VS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap, bool p_bicubic_upscale) {
void RasterizerSceneGLES3::environment_set_glow(RID p_env, bool p_enable, int p_level_flags, float p_intensity, float p_strength, float p_bloom_threshold, VS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap, bool p_bicubic_upscale, bool p_high_quality) {
Environment *env = environment_owner.getornull(p_env);
ERR_FAIL_COND(!env);

Expand All @@ -852,6 +852,7 @@ void RasterizerSceneGLES3::environment_set_glow(RID p_env, bool p_enable, int p_
env->glow_hdr_bleed_scale = p_hdr_bleed_scale;
env->glow_hdr_luminance_cap = p_hdr_luminance_cap;
env->glow_bicubic_upscale = p_bicubic_upscale;
env->glow_high_quality = p_high_quality;
}
void RasterizerSceneGLES3::environment_set_fog(RID p_env, bool p_enable, float p_begin, float p_end, RID p_gradient_texture) {
}
Expand Down Expand Up @@ -3805,6 +3806,7 @@ void RasterizerSceneGLES3::_post_process(Environment *env, const CameraMatrix &p
}

state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::GLOW_GAUSSIAN_HORIZONTAL, true);
state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::USE_GLOW_HIGH_QUALITY, env->glow_high_quality);
state.effect_blur_shader.bind();
state.effect_blur_shader.set_uniform(EffectBlurShaderGLES3::PIXEL_SIZE, Vector2(1.0 / vp_w, 1.0 / vp_h));
state.effect_blur_shader.set_uniform(EffectBlurShaderGLES3::LOD, float(i));
Expand Down
4 changes: 3 additions & 1 deletion drivers/gles3/rasterizer_scene_gles3.h
Original file line number Diff line number Diff line change
Expand Up @@ -408,6 +408,7 @@ class RasterizerSceneGLES3 : public RasterizerScene {
float glow_hdr_bleed_scale;
float glow_hdr_luminance_cap;
bool glow_bicubic_upscale;
bool glow_high_quality;

VS::EnvironmentToneMapper tone_mapper;
float tone_mapper_exposure;
Expand Down Expand Up @@ -488,6 +489,7 @@ class RasterizerSceneGLES3 : public RasterizerScene {
glow_hdr_bleed_scale(2.0),
glow_hdr_luminance_cap(12.0),
glow_bicubic_upscale(false),
glow_high_quality(false),
tone_mapper(VS::ENV_TONE_MAPPER_LINEAR),
tone_mapper_exposure(1.0),
tone_mapper_exposure_white(1.0),
Expand Down Expand Up @@ -544,7 +546,7 @@ class RasterizerSceneGLES3 : public RasterizerScene {
virtual void environment_set_dof_blur_near(RID p_env, bool p_enable, float p_distance, float p_transition, float p_amount, VS::EnvironmentDOFBlurQuality p_quality);
virtual void environment_set_dof_blur_far(RID p_env, bool p_enable, float p_distance, float p_transition, float p_amount, VS::EnvironmentDOFBlurQuality p_quality);

virtual void environment_set_glow(RID p_env, bool p_enable, int p_level_flags, float p_intensity, float p_strength, float p_bloom_threshold, VS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap, bool p_bicubic_upscale);
virtual void environment_set_glow(RID p_env, bool p_enable, int p_level_flags, float p_intensity, float p_strength, float p_bloom_threshold, VS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap, bool p_bicubic_upscale, bool p_high_quality);
virtual void environment_set_fog(RID p_env, bool p_enable, float p_begin, float p_end, RID p_gradient_texture);

virtual void environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_fade_in, float p_fade_out, float p_depth_tolerance, bool p_roughness);
Expand Down
29 changes: 28 additions & 1 deletion drivers/gles3/shaders/effect_blur.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -140,16 +140,43 @@ void main() {
#ifdef GLOW_GAUSSIAN_HORIZONTAL
vec2 pix_size = pixel_size;
pix_size *= 0.5; //reading from larger buffer, so use more samples

#ifdef USE_GLOW_HIGH_QUALITY
// Sample from two lines to capture single-pixel features.
// This is significantly slower, but looks better and is more stable for moving objects.
vec4 color = textureLod(source_color, uv_interp + vec2(0.0, 0.0) * pix_size, lod) * 0.152781;
color += textureLod(source_color, uv_interp + vec2(1.0, 0.0) * pix_size, lod) * 0.144599;
color += textureLod(source_color, uv_interp + vec2(2.0, 0.0) * pix_size, lod) * 0.122589;
color += textureLod(source_color, uv_interp + vec2(3.0, 0.0) * pix_size, lod) * 0.093095;
color += textureLod(source_color, uv_interp + vec2(4.0, 0.0) * pix_size, lod) * 0.063327;
color += textureLod(source_color, uv_interp + vec2(-1.0, 0.0) * pix_size, lod) * 0.144599;
color += textureLod(source_color, uv_interp + vec2(-2.0, 0.0) * pix_size, lod) * 0.122589;
color += textureLod(source_color, uv_interp + vec2(-3.0, 0.0) * pix_size, lod) * 0.093095;
color += textureLod(source_color, uv_interp + vec2(-4.0, 0.0) * pix_size, lod) * 0.063327;

color += textureLod(source_color, uv_interp + vec2(0.0, 1.0) * pix_size, lod) * 0.152781;
color += textureLod(source_color, uv_interp + vec2(1.0, 1.0) * pix_size, lod) * 0.144599;
color += textureLod(source_color, uv_interp + vec2(2.0, 1.0) * pix_size, lod) * 0.122589;
color += textureLod(source_color, uv_interp + vec2(3.0, 1.0) * pix_size, lod) * 0.093095;
color += textureLod(source_color, uv_interp + vec2(4.0, 1.0) * pix_size, lod) * 0.063327;
color += textureLod(source_color, uv_interp + vec2(-1.0, 1.0) * pix_size, lod) * 0.144599;
color += textureLod(source_color, uv_interp + vec2(-2.0, 1.0) * pix_size, lod) * 0.122589;
color += textureLod(source_color, uv_interp + vec2(-3.0, 1.0) * pix_size, lod) * 0.093095;
color += textureLod(source_color, uv_interp + vec2(-4.0, 1.0) * pix_size, lod) * 0.063327;
color *= 0.5;
#else
vec4 color = textureLod(source_color, uv_interp + vec2(0.0, 0.0) * pix_size, lod) * 0.174938;
color += textureLod(source_color, uv_interp + vec2(1.0, 0.0) * pix_size, lod) * 0.165569;
color += textureLod(source_color, uv_interp + vec2(2.0, 0.0) * pix_size, lod) * 0.140367;
color += textureLod(source_color, uv_interp + vec2(3.0, 0.0) * pix_size, lod) * 0.106595;
color += textureLod(source_color, uv_interp + vec2(-1.0, 0.0) * pix_size, lod) * 0.165569;
color += textureLod(source_color, uv_interp + vec2(-2.0, 0.0) * pix_size, lod) * 0.140367;
color += textureLod(source_color, uv_interp + vec2(-3.0, 0.0) * pix_size, lod) * 0.106595;
#endif //USE_GLOW_HIGH_QUALITY

color *= glow_strength;
frag_color = color;
#endif
#endif //GLOW_GAUSSIAN_HORIZONTAL

#ifdef GLOW_GAUSSIAN_VERTICAL
vec4 color = textureLod(source_color, uv_interp + vec2(0.0, 0.0) * pixel_size, lod) * 0.288713;
Expand Down
Loading