From 18ebd22000478dffc91255e89b9845f74b05b606 Mon Sep 17 00:00:00 2001 From: Juan Linietsky Date: Thu, 8 Dec 2016 09:48:38 -0300 Subject: [PATCH] Multi stage glow with light bleeding from HDR --- drivers/gles3/rasterizer_scene_gles3.cpp | 160 +++++++++++++++++++- drivers/gles3/rasterizer_scene_gles3.h | 22 ++- drivers/gles3/rasterizer_storage_gles3.cpp | 4 +- drivers/gles3/shaders/effect_blur.glsl | 67 +++++++++ drivers/gles3/shaders/tonemap.glsl | 81 ++++++++++ scene/resources/environment.cpp | 165 ++++++++++++++++++++- scene/resources/environment.h | 49 +++++- servers/visual/rasterizer.h | 2 +- servers/visual/visual_server_raster.h | 2 +- servers/visual_server.h | 6 +- 10 files changed, 536 insertions(+), 22 deletions(-) diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp index 4abeef89bec..ec304e7a46d 100644 --- a/drivers/gles3/rasterizer_scene_gles3.cpp +++ b/drivers/gles3/rasterizer_scene_gles3.cpp @@ -850,7 +850,19 @@ void RasterizerSceneGLES3::environment_set_ambient_light(RID p_env, const Color& } -void RasterizerSceneGLES3::environment_set_glow(RID p_env,bool p_enable,int p_radius,float p_intensity,float p_strength,float p_bloom_treshold,VS::EnvironmentGlowBlendMode p_blend_mode){ +void RasterizerSceneGLES3::environment_set_glow(RID p_env,bool p_enable,int p_level_flags,float p_intensity,float p_strength,float p_bloom_treshold,VS::EnvironmentGlowBlendMode p_blend_mode,float p_hdr_bleed_treshold,float p_hdr_bleed_scale) { + + Environment *env=environment_owner.getornull(p_env); + ERR_FAIL_COND(!env); + + env->glow_enabled=p_enable; + env->glow_levels=p_level_flags; + env->glow_intensity=p_intensity; + env->glow_strength=p_strength; + env->glow_bloom=p_bloom_treshold; + env->glow_blend_mode=p_blend_mode; + env->glow_hdr_bleed_treshold=p_hdr_bleed_treshold; + env->glow_hdr_bleed_scale=p_hdr_bleed_scale; } void RasterizerSceneGLES3::environment_set_fog(RID p_env,bool p_enable,float p_begin,float p_end,RID p_gradient_texture){ @@ -3155,6 +3167,95 @@ void RasterizerSceneGLES3::_post_process(Environment *env){ } + int max_glow_level=-1; + int glow_mask=0; + + + if (env->glow_enabled) { + + + for(int i=0;iglow_levels&(1<=storage->frame.current_rt->effects.mip_maps[1].sizes.size()) { + max_glow_level=storage->frame.current_rt->effects.mip_maps[1].sizes.size()-1; + glow_mask|=1<shaders.copy.set_conditional(CopyShaderGLES3::GAUSSIAN_HORIZONTAL,true); + + for(int i=0;i<(max_glow_level+1);i++) { + + + int vp_w = storage->frame.current_rt->effects.mip_maps[1].sizes[i].width; + int vp_h = storage->frame.current_rt->effects.mip_maps[1].sizes[i].height; + glViewport(0,0,vp_w,vp_h); + //horizontal pass + if (i==0) { + state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::GLOW_FIRST_PASS,true); + state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::GLOW_USE_AUTO_EXPOSURE,env->auto_exposure); + } + + state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::GLOW_GAUSSIAN_HORIZONTAL,true); + 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)); + state.effect_blur_shader.set_uniform(EffectBlurShaderGLES3::GLOW_STRENGTH,env->glow_strength); + + glActiveTexture(GL_TEXTURE0); + if (i==0) { + glBindTexture(GL_TEXTURE_2D,composite_from); + + state.effect_blur_shader.set_uniform(EffectBlurShaderGLES3::EXPOSURE,env->tone_mapper_exposure); + if (env->auto_exposure) { + state.effect_blur_shader.set_uniform(EffectBlurShaderGLES3::AUTO_EXPOSURE_GREY,env->auto_exposure_grey); + } + + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D,storage->frame.current_rt->exposure.color); + + state.effect_blur_shader.set_uniform(EffectBlurShaderGLES3::GLOW_BLOOM,env->glow_bloom); + state.effect_blur_shader.set_uniform(EffectBlurShaderGLES3::GLOW_HDR_TRESHOLD,env->glow_hdr_bleed_treshold); + state.effect_blur_shader.set_uniform(EffectBlurShaderGLES3::GLOW_HDR_SCALE,env->glow_hdr_bleed_scale); + + } else { + glBindTexture(GL_TEXTURE_2D,storage->frame.current_rt->effects.mip_maps[0].color); //previous level, since mipmaps[0] starts one level bigger + } + glBindFramebuffer(GL_FRAMEBUFFER,storage->frame.current_rt->effects.mip_maps[1].sizes[i].fbo); + _copy_screen(); + state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::GLOW_GAUSSIAN_HORIZONTAL,false); + state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::GLOW_FIRST_PASS,false); + state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::GLOW_USE_AUTO_EXPOSURE,false); + + //vertical pass + state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::GLOW_GAUSSIAN_VERTICAL,true); + 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)); + state.effect_blur_shader.set_uniform(EffectBlurShaderGLES3::GLOW_STRENGTH,env->glow_strength); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D,storage->frame.current_rt->effects.mip_maps[1].color); + glBindFramebuffer(GL_FRAMEBUFFER,storage->frame.current_rt->effects.mip_maps[0].sizes[i+1].fbo); //next level, since mipmaps[0] starts one level bigger + _copy_screen(); + state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::GLOW_GAUSSIAN_VERTICAL,false); + } + + glViewport(0,0,storage->frame.current_rt->width,storage->frame.current_rt->height); + + } + + + + glBindFramebuffer(GL_FRAMEBUFFER,storage->frame.current_rt->fbo); glActiveTexture(GL_TEXTURE0); @@ -3166,11 +3267,55 @@ void RasterizerSceneGLES3::_post_process(Environment *env){ state.tonemap_shader.set_conditional(TonemapShaderGLES3::USE_AUTO_EXPOSURE,env->auto_exposure); + + + if (max_glow_level>=0) { + + + for(int i=0;i<(max_glow_level+1);i++) { + + if (glow_mask&(1<glow_blend_mode==VS::GLOW_BLEND_MODE_SCREEN); + state.tonemap_shader.set_conditional(TonemapShaderGLES3::USE_GLOW_SOFTLIGHT,env->glow_blend_mode==VS::GLOW_BLEND_MODE_SOFTLIGHT); + state.tonemap_shader.set_conditional(TonemapShaderGLES3::USE_GLOW_REPLACE,env->glow_blend_mode==VS::GLOW_BLEND_MODE_REPLACE); + glActiveTexture(GL_TEXTURE2); + glBindTexture(GL_TEXTURE_2D,storage->frame.current_rt->effects.mip_maps[0].color); + + } + state.tonemap_shader.bind(); state.tonemap_shader.set_uniform(TonemapShaderGLES3::EXPOSURE,env->tone_mapper_exposure); state.tonemap_shader.set_uniform(TonemapShaderGLES3::WHITE,env->tone_mapper_exposure_white); + if (max_glow_level>=0) { + + state.tonemap_shader.set_uniform(TonemapShaderGLES3::GLOW_INTENSITY,env->glow_intensity); + } if (env->auto_exposure) { @@ -3180,6 +3325,8 @@ void RasterizerSceneGLES3::_post_process(Environment *env){ } + + _copy_screen(); //turn off everything used @@ -3187,7 +3334,16 @@ void RasterizerSceneGLES3::_post_process(Environment *env){ state.tonemap_shader.set_conditional(TonemapShaderGLES3::USE_FILMIC_TONEMAPPER,false); state.tonemap_shader.set_conditional(TonemapShaderGLES3::USE_ACES_TONEMAPPER,false); state.tonemap_shader.set_conditional(TonemapShaderGLES3::USE_REINDHART_TONEMAPPER,false); - + state.tonemap_shader.set_conditional(TonemapShaderGLES3::USE_GLOW_LEVEL1,false); + state.tonemap_shader.set_conditional(TonemapShaderGLES3::USE_GLOW_LEVEL2,false); + state.tonemap_shader.set_conditional(TonemapShaderGLES3::USE_GLOW_LEVEL3,false); + state.tonemap_shader.set_conditional(TonemapShaderGLES3::USE_GLOW_LEVEL4,false); + state.tonemap_shader.set_conditional(TonemapShaderGLES3::USE_GLOW_LEVEL5,false); + state.tonemap_shader.set_conditional(TonemapShaderGLES3::USE_GLOW_LEVEL6,false); + state.tonemap_shader.set_conditional(TonemapShaderGLES3::USE_GLOW_LEVEL7,false); + state.tonemap_shader.set_conditional(TonemapShaderGLES3::USE_GLOW_REPLACE,false); + state.tonemap_shader.set_conditional(TonemapShaderGLES3::USE_GLOW_SCREEN,false); + state.tonemap_shader.set_conditional(TonemapShaderGLES3::USE_GLOW_SOFTLIGHT,false); } void RasterizerSceneGLES3::render_scene(const Transform& p_cam_transform,const CameraMatrix& p_cam_projection,bool p_cam_ortogonal,InstanceBase** p_cull_result,int p_cull_count,RID* p_light_cull_result,int p_light_cull_count,RID* p_reflection_probe_cull_result,int p_reflection_probe_cull_count,RID p_environment,RID p_shadow_atlas,RID p_reflection_atlas,RID p_reflection_probe,int p_reflection_probe_pass){ diff --git a/drivers/gles3/rasterizer_scene_gles3.h b/drivers/gles3/rasterizer_scene_gles3.h index b0a875aa168..6ca4529ed92 100644 --- a/drivers/gles3/rasterizer_scene_gles3.h +++ b/drivers/gles3/rasterizer_scene_gles3.h @@ -341,6 +341,15 @@ public: Color ssao_color; bool ssao_filter; + bool glow_enabled; + int glow_levels; + float glow_intensity; + float glow_strength; + float glow_bloom; + VS::EnvironmentGlowBlendMode glow_blend_mode; + float glow_hdr_bleed_treshold; + float glow_hdr_bleed_scale; + VS::EnvironmentToneMapper tone_mapper; float tone_mapper_exposure; float tone_mapper_exposure_white; @@ -350,6 +359,7 @@ public: float auto_exposure_max; float auto_exposure_grey; + Environment() { bg_mode=VS::ENV_BG_CLEAR_COLOR; skybox_scale=1.0; @@ -385,6 +395,16 @@ public: auto_exposure_max=8; auto_exposure_grey=0.4; + glow_enabled=false; + glow_levels=(1<<2)|(1<<4); + glow_intensity=0.8; + glow_strength=1.0; + glow_bloom=0.0; + glow_blend_mode=VS::GLOW_BLEND_MODE_SOFTLIGHT; + glow_hdr_bleed_treshold=1.0; + glow_hdr_bleed_scale=2.0; + + } }; @@ -400,7 +420,7 @@ public: virtual void environment_set_canvas_max_layer(RID p_env,int p_max_layer); virtual void environment_set_ambient_light(RID p_env,const Color& p_color,float p_energy=1.0,float p_skybox_contribution=0.0); - virtual void environment_set_glow(RID p_env,bool p_enable,int p_radius,float p_intensity,float p_strength,float p_bloom_treshold,VS::EnvironmentGlowBlendMode p_blend_mode); + virtual void environment_set_glow(RID p_env,bool p_enable,int p_level_flags,float p_intensity,float p_strength,float p_bloom_treshold,VS::EnvironmentGlowBlendMode p_blend_mode,float p_hdr_bleed_treshold,float p_hdr_bleed_scale); 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_accel,float p_fade,float p_depth_tolerance,bool p_smooth,bool p_roughness); diff --git a/drivers/gles3/rasterizer_storage_gles3.cpp b/drivers/gles3/rasterizer_storage_gles3.cpp index ddb60273e4a..cfa50f6100d 100644 --- a/drivers/gles3/rasterizer_storage_gles3.cpp +++ b/drivers/gles3/rasterizer_storage_gles3.cpp @@ -5020,8 +5020,8 @@ void RasterizerStorageGLES3::_render_target_allocate(RenderTarget *rt){ w>>=1; h>>=1; - if (w<32 || h<32) - break; //going less than 32 is pointless + if (w<2 || h<2) + break; level++; diff --git a/drivers/gles3/shaders/effect_blur.glsl b/drivers/gles3/shaders/effect_blur.glsl index 211b60ca2ec..589af64d444 100644 --- a/drivers/gles3/shaders/effect_blur.glsl +++ b/drivers/gles3/shaders/effect_blur.glsl @@ -35,6 +35,31 @@ uniform vec4 ssao_color; #endif +#if defined (GLOW_GAUSSIAN_HORIZONTAL) || defined(GLOW_GAUSSIAN_VERTICAL) + +uniform float glow_strength; + +#endif + + +#ifdef GLOW_FIRST_PASS + +uniform float exposure; +uniform float white; + +#ifdef GLOW_USE_AUTO_EXPOSURE + +uniform highp sampler2D source_auto_exposure; //texunit:1 +uniform highp float auto_exposure_grey; + +#endif + +uniform float glow_bloom; +uniform float glow_hdr_treshold; +uniform float glow_hdr_scale; + +#endif + void main() { @@ -57,6 +82,48 @@ void main() { frag_color = color; #endif + + +#ifdef GLOW_GAUSSIAN_HORIZONTAL + vec4 color =textureLod( source_color, uv_interp+vec2( 0.0, 0.0)*pixel_size,lod )*0.174938; + color+=textureLod( source_color, uv_interp+vec2( 1.0, 0.0)*pixel_size,lod )*0.165569; + color+=textureLod( source_color, uv_interp+vec2( 2.0, 0.0)*pixel_size,lod )*0.140367; + color+=textureLod( source_color, uv_interp+vec2( 3.0, 0.0)*pixel_size,lod )*0.106595; + color+=textureLod( source_color, uv_interp+vec2(-1.0, 0.0)*pixel_size,lod )*0.165569; + color+=textureLod( source_color, uv_interp+vec2(-2.0, 0.0)*pixel_size,lod )*0.140367; + color+=textureLod( source_color, uv_interp+vec2(-3.0, 0.0)*pixel_size,lod )*0.165569; + color*=glow_strength; + frag_color = color; +#endif + +#ifdef GLOW_GAUSSIAN_VERTICAL + vec4 color =textureLod( source_color, uv_interp+vec2(0.0, 0.0)*pixel_size,lod )*0.174938; + color+=textureLod( source_color, uv_interp+vec2(0.0, 1.0)*pixel_size,lod )*0.165569; + color+=textureLod( source_color, uv_interp+vec2(0.0, 2.0)*pixel_size,lod )*0.140367; + color+=textureLod( source_color, uv_interp+vec2(0.0, 3.0)*pixel_size,lod )*0.106595; + color+=textureLod( source_color, uv_interp+vec2(0.0,-1.0)*pixel_size,lod )*0.165569; + color+=textureLod( source_color, uv_interp+vec2(0.0,-2.0)*pixel_size,lod )*0.140367; + color+=textureLod( source_color, uv_interp+vec2(0.0,-3.0)*pixel_size,lod )*0.165569; + color*=glow_strength; + frag_color = color; +#endif + +#ifdef GLOW_FIRST_PASS + +#ifdef GLOW_USE_AUTO_EXPOSURE + + frag_color/=texelFetch(source_auto_exposure,ivec2(0,0),0).r/auto_exposure_grey; +#endif + frag_color*=exposure; + + float luminance = max(frag_color.r,max(frag_color.g,frag_color.b)); + float feedback = max( smoothstep(glow_hdr_treshold,glow_hdr_treshold+glow_hdr_scale,luminance), glow_bloom ); + + frag_color *= feedback; + +#endif + + #ifdef SIMPLE_COPY vec4 color =textureLod( source_color, uv_interp,0.0); frag_color = color; diff --git a/drivers/gles3/shaders/tonemap.glsl b/drivers/gles3/shaders/tonemap.glsl index 566d194a02c..8ee51e9d0c4 100644 --- a/drivers/gles3/shaders/tonemap.glsl +++ b/drivers/gles3/shaders/tonemap.glsl @@ -2,17 +2,24 @@ layout(location=0) in highp vec4 vertex_attrib; +layout(location=4) in vec2 uv_in; + +out vec2 uv_interp; + void main() { gl_Position = vertex_attrib; + uv_interp = uv_in; } [fragment] +in vec2 uv_interp; + uniform highp sampler2D source; //texunit:0 uniform float exposure; @@ -25,6 +32,12 @@ uniform highp float auto_exposure_grey; #endif +#if defined(USE_GLOW_LEVEL1) || defined(USE_GLOW_LEVEL2) || defined(USE_GLOW_LEVEL3) || defined(USE_GLOW_LEVEL4) || defined(USE_GLOW_LEVEL5) || defined(USE_GLOW_LEVEL6) || defined(USE_GLOW_LEVEL7) + +uniform highp sampler2D source_glow; //texunit:2 +uniform highp float glow_intensity; + +#endif layout(location = 0) out vec4 frag_color; @@ -43,6 +56,74 @@ void main() { color*=exposure; +#if defined(USE_GLOW_LEVEL1) || defined(USE_GLOW_LEVEL2) || defined(USE_GLOW_LEVEL3) || defined(USE_GLOW_LEVEL4) || defined(USE_GLOW_LEVEL5) || defined(USE_GLOW_LEVEL6) || defined(USE_GLOW_LEVEL7) + vec3 glow = vec3(0.0); + +#ifdef USE_GLOW_LEVEL1 + glow+=textureLod(source_glow,uv_interp,1.0).rgb; +#endif + +#ifdef USE_GLOW_LEVEL2 + glow+=textureLod(source_glow,uv_interp,2.0).rgb; +#endif + +#ifdef USE_GLOW_LEVEL3 + glow+=textureLod(source_glow,uv_interp,3.0).rgb; +#endif + +#ifdef USE_GLOW_LEVEL4 + glow+=textureLod(source_glow,uv_interp,4.0).rgb; +#endif + +#ifdef USE_GLOW_LEVEL5 + glow+=textureLod(source_glow,uv_interp,5.0).rgb; +#endif + +#ifdef USE_GLOW_LEVEL6 + glow+=textureLod(source_glow,uv_interp,6.0).rgb; +#endif + +#ifdef USE_GLOW_LEVEL7 + glow+=textureLod(source_glow,uv_interp,7.0).rgb; +#endif + + + glow *= glow_intensity; + + + +#ifdef USE_GLOW_REPLACE + + color.rgb = glow; + +#endif + +#ifdef USE_GLOW_SCREEN + + color.rgb = clamp((color.rgb + glow) - (color.rgb * glow), 0.0, 1.0); + +#endif + +#ifdef USE_GLOW_SOFTLIGHT + + { + + glow = (glow * 0.5) + 0.5; + color.r = (glow.r <= 0.5) ? (color.r - (1.0 - 2.0 * glow.r) * color.r * (1.0 - color.r)) : (((glow.r > 0.5) && (color.r <= 0.25)) ? (color.r + (2.0 * glow.r - 1.0) * (4.0 * color.r * (4.0 * color.r + 1.0) * (color.r - 1.0) + 7.0 * color.r)) : (color.r + (2.0 * glow.r - 1.0) * (sqrt(color.r) - color.r))); + color.g = (glow.g <= 0.5) ? (color.g - (1.0 - 2.0 * glow.g) * color.g * (1.0 - color.g)) : (((glow.g > 0.5) && (color.g <= 0.25)) ? (color.g + (2.0 * glow.g - 1.0) * (4.0 * color.g * (4.0 * color.g + 1.0) * (color.g - 1.0) + 7.0 * color.g)) : (color.g + (2.0 * glow.g - 1.0) * (sqrt(color.g) - color.g))); + color.b = (glow.b <= 0.5) ? (color.b - (1.0 - 2.0 * glow.b) * color.b * (1.0 - color.b)) : (((glow.b > 0.5) && (color.b <= 0.25)) ? (color.b + (2.0 * glow.b - 1.0) * (4.0 * color.b * (4.0 * color.b + 1.0) * (color.b - 1.0) + 7.0 * color.b)) : (color.b + (2.0 * glow.b - 1.0) * (sqrt(color.b) - color.b))); + } + +#endif + +#if !defined(USE_GLOW_SCREEN) && !defined(USE_GLOW_SOFTLIGHT) && !defined(USE_GLOW_REPLACE) + color.rgb+=glow; +#endif + + +#endif + + #ifdef USE_REINDHART_TONEMAPPER { diff --git a/scene/resources/environment.cpp b/scene/resources/environment.cpp index 2b691125d0d..eb393f2ad11 100644 --- a/scene/resources/environment.cpp +++ b/scene/resources/environment.cpp @@ -474,6 +474,110 @@ bool Environment::is_ssao_blur_enabled() const { return ssao_blur; } +void Environment::set_glow_enabled(bool p_enabled) { + + glow_enabled=p_enabled; + VS::get_singleton()->environment_set_glow(environment,glow_enabled,glow_levels,glow_intensity,glow_strength,glow_bloom,VS::EnvironmentGlowBlendMode(glow_blend_mode),glow_hdr_bleed_treshold,glow_hdr_bleed_treshold); +} + +bool Environment::is_glow_enabled() const{ + + return glow_enabled; +} + +void Environment::set_glow_level(int p_level,bool p_enabled){ + + ERR_FAIL_INDEX(p_level,VS::MAX_GLOW_LEVELS); + + if (p_enabled) + glow_levels|=(1<environment_set_glow(environment,glow_enabled,glow_levels,glow_intensity,glow_strength,glow_bloom,VS::EnvironmentGlowBlendMode(glow_blend_mode),glow_hdr_bleed_treshold,glow_hdr_bleed_treshold); + +} +bool Environment::is_glow_level_enabled(int p_level) const{ + + ERR_FAIL_INDEX_V(p_level,VS::MAX_GLOW_LEVELS,false); + + return glow_levels&(1<environment_set_glow(environment,glow_enabled,glow_levels,glow_intensity,glow_strength,glow_bloom,VS::EnvironmentGlowBlendMode(glow_blend_mode),glow_hdr_bleed_treshold,glow_hdr_bleed_treshold); + +} +float Environment::get_glow_intensity() const{ + + return glow_intensity; +} + +void Environment::set_glow_strength(float p_strength){ + + glow_strength=p_strength; + VS::get_singleton()->environment_set_glow(environment,glow_enabled,glow_levels,glow_intensity,glow_strength,glow_bloom,VS::EnvironmentGlowBlendMode(glow_blend_mode),glow_hdr_bleed_treshold,glow_hdr_bleed_treshold); + +} +float Environment::get_glow_strength() const{ + + return glow_strength; +} + +void Environment::set_glow_bloom(float p_treshold){ + + glow_bloom=p_treshold; + + VS::get_singleton()->environment_set_glow(environment,glow_enabled,glow_levels,glow_intensity,glow_strength,glow_bloom,VS::EnvironmentGlowBlendMode(glow_blend_mode),glow_hdr_bleed_treshold,glow_hdr_bleed_treshold); + +} +float Environment::get_glow_bloom() const{ + + return glow_bloom; +} + +void Environment::set_glow_blend_mode(GlowBlendMode p_mode){ + + glow_blend_mode=p_mode; + + VS::get_singleton()->environment_set_glow(environment,glow_enabled,glow_levels,glow_intensity,glow_strength,glow_bloom,VS::EnvironmentGlowBlendMode(glow_blend_mode),glow_hdr_bleed_treshold,glow_hdr_bleed_treshold); + +} +Environment::GlowBlendMode Environment::get_glow_blend_mode() const{ + + return glow_blend_mode; +} + +void Environment::set_glow_hdr_bleed_treshold(float p_treshold){ + + glow_hdr_bleed_treshold=p_treshold; + + VS::get_singleton()->environment_set_glow(environment,glow_enabled,glow_levels,glow_intensity,glow_strength,glow_bloom,VS::EnvironmentGlowBlendMode(glow_blend_mode),glow_hdr_bleed_treshold,glow_hdr_bleed_treshold); + +} +float Environment::get_glow_hdr_bleed_treshold() const{ + + return glow_hdr_bleed_treshold; +} + +void Environment::set_glow_hdr_bleed_scale(float p_scale){ + + glow_hdr_bleed_scale=p_scale; + + VS::get_singleton()->environment_set_glow(environment,glow_enabled,glow_levels,glow_intensity,glow_strength,glow_bloom,VS::EnvironmentGlowBlendMode(glow_blend_mode),glow_hdr_bleed_treshold,glow_hdr_bleed_treshold); + +} +float Environment::get_glow_hdr_bleed_scale() const{ + + return glow_hdr_bleed_scale; +} + + + + void Environment::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_background","mode"),&Environment::set_background); @@ -530,7 +634,7 @@ void Environment::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_ssr_rough","rough"),&Environment::set_ssr_rough); ObjectTypeDB::bind_method(_MD("is_ssr_rough"),&Environment::is_ssr_rough); - ADD_PROPERTY(PropertyInfo(Variant::BOOL,"ss_reflections/enable"),_SCS("set_ssr_enabled"),_SCS("is_ssr_enabled") ); + ADD_PROPERTY(PropertyInfo(Variant::BOOL,"ss_reflections/enabled"),_SCS("set_ssr_enabled"),_SCS("is_ssr_enabled") ); ADD_PROPERTY(PropertyInfo(Variant::INT,"ss_reflections/max_steps",PROPERTY_HINT_RANGE,"1,512,1"),_SCS("set_ssr_max_steps"),_SCS("get_ssr_max_steps") ); ADD_PROPERTY(PropertyInfo(Variant::REAL,"ss_reflections/accel",PROPERTY_HINT_RANGE,"0,4,0.01"),_SCS("set_ssr_accel"),_SCS("get_ssr_accel") ); ADD_PROPERTY(PropertyInfo(Variant::REAL,"ss_reflections/fade",PROPERTY_HINT_EXP_EASING),_SCS("set_ssr_fade"),_SCS("get_ssr_fade") ); @@ -565,7 +669,7 @@ void Environment::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_ssao_blur","enabled"),&Environment::set_ssao_blur); ObjectTypeDB::bind_method(_MD("is_ssao_blur_enabled"),&Environment::is_ssao_blur_enabled); - ADD_PROPERTY(PropertyInfo(Variant::BOOL,"ambient_occlusion/enable"),_SCS("set_ssao_enabled"),_SCS("is_ssao_enabled") ); + ADD_PROPERTY(PropertyInfo(Variant::BOOL,"ambient_occlusion/enabled"),_SCS("set_ssao_enabled"),_SCS("is_ssao_enabled") ); ADD_PROPERTY(PropertyInfo(Variant::REAL,"ambient_occlusion/radius",PROPERTY_HINT_RANGE,"0.1,16,0.1"),_SCS("set_ssao_radius"),_SCS("get_ssao_radius") ); ADD_PROPERTY(PropertyInfo(Variant::REAL,"ambient_occlusion/intensity",PROPERTY_HINT_RANGE,"0.0,9,0.1"),_SCS("set_ssao_intensity"),_SCS("get_ssao_intensity") ); ADD_PROPERTY(PropertyInfo(Variant::REAL,"ambient_occlusion/radius2",PROPERTY_HINT_RANGE,"0.0,16,0.1"),_SCS("set_ssao_radius2"),_SCS("get_ssao_radius2") ); @@ -576,6 +680,48 @@ void Environment::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL,"ambient_occlusion/blur"),_SCS("set_ssao_blur"),_SCS("is_ssao_blur_enabled") ); + ObjectTypeDB::bind_method(_MD("set_glow_enabled","enabled"),&Environment::set_glow_enabled); + ObjectTypeDB::bind_method(_MD("is_glow_enabled"),&Environment::is_glow_enabled); + + ObjectTypeDB::bind_method(_MD("set_glow_level","idx","enabled"),&Environment::set_glow_level); + ObjectTypeDB::bind_method(_MD("is_glow_level_enabled","idx"),&Environment::is_glow_level_enabled); + + ObjectTypeDB::bind_method(_MD("set_glow_intensity","intensity"),&Environment::set_glow_intensity); + ObjectTypeDB::bind_method(_MD("get_glow_intensity"),&Environment::get_glow_intensity); + + ObjectTypeDB::bind_method(_MD("set_glow_strength","strength"),&Environment::set_glow_strength); + ObjectTypeDB::bind_method(_MD("get_glow_strength"),&Environment::get_glow_strength); + + ObjectTypeDB::bind_method(_MD("set_glow_bloom","amount"),&Environment::set_glow_bloom); + ObjectTypeDB::bind_method(_MD("get_glow_bloom"),&Environment::get_glow_bloom); + + ObjectTypeDB::bind_method(_MD("set_glow_blend_mode","mode"),&Environment::set_glow_blend_mode); + ObjectTypeDB::bind_method(_MD("get_glow_blend_mode"),&Environment::get_glow_blend_mode); + + ObjectTypeDB::bind_method(_MD("set_glow_hdr_bleed_treshold","treshold"),&Environment::set_glow_hdr_bleed_treshold); + ObjectTypeDB::bind_method(_MD("get_glow_hdr_bleed_treshold"),&Environment::get_glow_hdr_bleed_treshold); + + ObjectTypeDB::bind_method(_MD("set_glow_hdr_bleed_scale","scale"),&Environment::set_glow_hdr_bleed_scale); + ObjectTypeDB::bind_method(_MD("get_glow_hdr_bleed_scale"),&Environment::get_glow_hdr_bleed_scale); + + + ADD_PROPERTY(PropertyInfo(Variant::BOOL,"glow/enabled"),_SCS("set_glow_enabled"),_SCS("is_glow_enabled") ); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL,"glow/levels/1"),_SCS("set_glow_level"),_SCS("is_glow_level_enabled"),0 ); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL,"glow/levels/2"),_SCS("set_glow_level"),_SCS("is_glow_level_enabled"),1 ); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL,"glow/levels/3"),_SCS("set_glow_level"),_SCS("is_glow_level_enabled"),2 ); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL,"glow/levels/4"),_SCS("set_glow_level"),_SCS("is_glow_level_enabled"),3 ); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL,"glow/levels/5"),_SCS("set_glow_level"),_SCS("is_glow_level_enabled"),4 ); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL,"glow/levels/6"),_SCS("set_glow_level"),_SCS("is_glow_level_enabled"),5 ); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL,"glow/levels/7"),_SCS("set_glow_level"),_SCS("is_glow_level_enabled"),6 ); + + ADD_PROPERTY(PropertyInfo(Variant::REAL,"glow/intensity",PROPERTY_HINT_RANGE,"0.0,8.0,0.01"),_SCS("set_glow_intensity"),_SCS("get_glow_intensity") ); + ADD_PROPERTY(PropertyInfo(Variant::REAL,"glow/strength",PROPERTY_HINT_RANGE,"0.0,2.0,0.01"),_SCS("set_glow_strength"),_SCS("get_glow_strength") ); + ADD_PROPERTY(PropertyInfo(Variant::REAL,"glow/bloom",PROPERTY_HINT_RANGE,"0.0,1.0,0.01"),_SCS("set_glow_bloom"),_SCS("get_glow_bloom") ); + ADD_PROPERTY(PropertyInfo(Variant::INT,"glow/blend_mode",PROPERTY_HINT_ENUM,"Additive,Screen,Softlight,Replace"),_SCS("set_glow_blend_mode"),_SCS("get_glow_blend_mode") ); + ADD_PROPERTY(PropertyInfo(Variant::REAL,"glow/hdr_treshold",PROPERTY_HINT_RANGE,"0.0,4.0,0.01"),_SCS("set_glow_hdr_bleed_treshold"),_SCS("get_glow_hdr_bleed_treshold") ); + ADD_PROPERTY(PropertyInfo(Variant::REAL,"glow/hdr_scale",PROPERTY_HINT_RANGE,"0.0,4.0,0.01"),_SCS("set_glow_hdr_bleed_scale"),_SCS("get_glow_hdr_bleed_scale") ); + + ObjectTypeDB::bind_method(_MD("set_tonemapper","mode"),&Environment::set_tonemapper); ObjectTypeDB::bind_method(_MD("get_tonemapper"),&Environment::get_tonemapper); @@ -601,12 +747,10 @@ void Environment::_bind_methods() { ObjectTypeDB::bind_method(_MD("get_tonemap_auto_exposure_grey"),&Environment::get_tonemap_auto_exposure_grey); - - ADD_PROPERTY(PropertyInfo(Variant::INT,"tonemap/mode",PROPERTY_HINT_ENUM,"Linear,Reindhart,Filmic,Aces"),_SCS("set_tonemapper"),_SCS("get_tonemapper") ); ADD_PROPERTY(PropertyInfo(Variant::REAL,"tonemap/exposure",PROPERTY_HINT_RANGE,"0,16,0.01"),_SCS("set_tonemap_exposure"),_SCS("get_tonemap_exposure") ); ADD_PROPERTY(PropertyInfo(Variant::REAL,"tonemap/white",PROPERTY_HINT_RANGE,"0,16,0.01"),_SCS("set_tonemap_white"),_SCS("get_tonemap_white") ); - ADD_PROPERTY(PropertyInfo(Variant::BOOL,"auto_exposure/enable"),_SCS("set_tonemap_auto_exposure"),_SCS("get_tonemap_auto_exposure") ); + ADD_PROPERTY(PropertyInfo(Variant::BOOL,"auto_exposure/enabled"),_SCS("set_tonemap_auto_exposure"),_SCS("get_tonemap_auto_exposure") ); ADD_PROPERTY(PropertyInfo(Variant::REAL,"auto_exposure/scale",PROPERTY_HINT_RANGE,"0.01,64,0.01"),_SCS("set_tonemap_auto_exposure_grey"),_SCS("get_tonemap_auto_exposure_grey") ); ADD_PROPERTY(PropertyInfo(Variant::REAL,"auto_exposure/min_luma",PROPERTY_HINT_RANGE,"0,16,0.01"),_SCS("set_tonemap_auto_exposure_min"),_SCS("get_tonemap_auto_exposure_min") ); ADD_PROPERTY(PropertyInfo(Variant::REAL,"auto_exposure/max_luma",PROPERTY_HINT_RANGE,"0,16,0.01"),_SCS("set_tonemap_auto_exposure_max"),_SCS("get_tonemap_auto_exposure_max") ); @@ -646,7 +790,7 @@ void Environment::_bind_methods() { BIND_CONSTANT(GLOW_BLEND_MODE_ADDITIVE); BIND_CONSTANT(GLOW_BLEND_MODE_SCREEN); BIND_CONSTANT(GLOW_BLEND_MODE_SOFTLIGHT); - BIND_CONSTANT(GLOW_BLEND_MODE_DISABLED); + BIND_CONSTANT(GLOW_BLEND_MODE_REPLACE); BIND_CONSTANT(TONE_MAPPER_LINEAR); BIND_CONSTANT(TONE_MAPPER_REINHARDT); BIND_CONSTANT(TONE_MAPPER_FILMIC); @@ -702,6 +846,15 @@ Environment::Environment() { ssao_direct_light_affect=false; ssao_blur=true; + glow_enabled=false; + glow_levels=(1<<2)|(1<<4); + glow_intensity=0.8; + glow_strength=1.0; + glow_bloom=0.0; + glow_blend_mode=GLOW_BLEND_MODE_SOFTLIGHT; + glow_hdr_bleed_treshold=1.0; + glow_hdr_bleed_scale=2.0; + } Environment::~Environment() { diff --git a/scene/resources/environment.h b/scene/resources/environment.h index 3cf9f550b4d..50c48165e86 100644 --- a/scene/resources/environment.h +++ b/scene/resources/environment.h @@ -49,12 +49,7 @@ public: BG_MAX }; - enum GlowBlendMode { - GLOW_BLEND_MODE_ADDITIVE, - GLOW_BLEND_MODE_SCREEN, - GLOW_BLEND_MODE_SOFTLIGHT, - GLOW_BLEND_MODE_DISABLED, - }; + enum ToneMapper { TONE_MAPPER_LINEAR, @@ -63,6 +58,12 @@ public: TONE_MAPPER_ACES }; + enum GlowBlendMode { + GLOW_BLEND_MODE_ADDITIVE, + GLOW_BLEND_MODE_SCREEN, + GLOW_BLEND_MODE_SOFTLIGHT, + GLOW_BLEND_MODE_REPLACE, + }; private: @@ -111,6 +112,15 @@ private: Color ssao_color; bool ssao_blur; + bool glow_enabled; + int glow_levels; + float glow_intensity; + float glow_strength; + float glow_bloom; + GlowBlendMode glow_blend_mode; + float glow_hdr_bleed_treshold; + float glow_hdr_bleed_scale; + protected: @@ -229,6 +239,31 @@ public: bool is_ssao_blur_enabled() const; + void set_glow_enabled(bool p_enabled); + bool is_glow_enabled() const; + + void set_glow_level(int p_level,bool p_enabled); + bool is_glow_level_enabled(int p_level) const; + + void set_glow_intensity(float p_intensity); + float get_glow_intensity() const; + + void set_glow_strength(float p_strength); + float get_glow_strength() const; + + void set_glow_bloom(float p_treshold); + float get_glow_bloom() const; + + void set_glow_blend_mode(GlowBlendMode p_mode); + GlowBlendMode get_glow_blend_mode() const; + + void set_glow_hdr_bleed_treshold(float p_treshold); + float get_glow_hdr_bleed_treshold() const; + + void set_glow_hdr_bleed_scale(float p_scale); + float get_glow_hdr_bleed_scale() const; + + virtual RID get_rid() const; @@ -240,8 +275,8 @@ public: VARIANT_ENUM_CAST(Environment::BGMode) -VARIANT_ENUM_CAST(Environment::GlowBlendMode) VARIANT_ENUM_CAST(Environment::ToneMapper) +VARIANT_ENUM_CAST(Environment::GlowBlendMode) #endif // ENVIRONMENT_H diff --git a/servers/visual/rasterizer.h b/servers/visual/rasterizer.h index 4f357afa68e..2b1829283ff 100644 --- a/servers/visual/rasterizer.h +++ b/servers/visual/rasterizer.h @@ -61,7 +61,7 @@ public: virtual void environment_set_canvas_max_layer(RID p_env,int p_max_layer)=0; virtual void environment_set_ambient_light(RID p_env,const Color& p_color,float p_energy=1.0,float p_skybox_contribution=0.0)=0; - virtual void environment_set_glow(RID p_env,bool p_enable,int p_radius,float p_intensity,float p_strength,float p_bloom_treshold,VS::EnvironmentGlowBlendMode p_blend_mode)=0; + virtual void environment_set_glow(RID p_env,bool p_enable,int p_level_flags,float p_intensity,float p_strength,float p_bloom_treshold,VS::EnvironmentGlowBlendMode p_blend_mode,float p_hdr_bleed_treshold,float p_hdr_bleed_scale)=0; virtual void environment_set_fog(RID p_env,bool p_enable,float p_begin,float p_end,RID p_gradient_texture)=0; virtual void environment_set_ssr(RID p_env,bool p_enable, int p_max_steps,float p_accel,float p_fade,float p_depth_tolerance,bool p_smooth,bool p_roughness)=0; diff --git a/servers/visual/visual_server_raster.h b/servers/visual/visual_server_raster.h index c7e49ede2c0..52c156cd6fb 100644 --- a/servers/visual/visual_server_raster.h +++ b/servers/visual/visual_server_raster.h @@ -879,7 +879,7 @@ public: BIND10(environment_set_ssao,RID ,bool , float , float , float,float,float , float ,const Color &,bool ) - BIND7(environment_set_glow,RID,bool ,int ,float ,float ,float ,EnvironmentGlowBlendMode ) + BIND9(environment_set_glow,RID,bool ,int ,float ,float ,float ,EnvironmentGlowBlendMode,float,float ) BIND5(environment_set_fog,RID,bool ,float ,float ,RID ) BIND9(environment_set_tonemap,RID,EnvironmentToneMapper, float ,float ,bool, float ,float ,float,float ) diff --git a/servers/visual_server.h b/servers/visual_server.h index 0b3a9771a8c..adc9f4960ce 100644 --- a/servers/visual_server.h +++ b/servers/visual_server.h @@ -79,6 +79,8 @@ public: ARRAY_WEIGHTS_SIZE=4, CANVAS_ITEM_Z_MIN=-4096, CANVAS_ITEM_Z_MAX=4096, + MAX_GLOW_LEVELS=7, + @@ -538,9 +540,9 @@ public: GLOW_BLEND_MODE_ADDITIVE, GLOW_BLEND_MODE_SCREEN, GLOW_BLEND_MODE_SOFTLIGHT, - GLOW_BLEND_MODE_DISABLED, + GLOW_BLEND_MODE_REPLACE, }; - virtual void environment_set_glow(RID p_env,bool p_enable,int p_radius,float p_intensity,float p_strength,float p_bloom_treshold,EnvironmentGlowBlendMode p_blend_mode)=0; + virtual void environment_set_glow(RID p_env,bool p_enable,int p_level_flags,float p_intensity,float p_strength,float p_bloom_treshold,EnvironmentGlowBlendMode p_blend_mode,float p_hdr_bleed_treshold,float p_hdr_bleed_scale)=0; virtual void environment_set_fog(RID p_env,bool p_enable,float p_begin,float p_end,RID p_gradient_texture)=0;