summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJuan Linietsky <reduzio@gmail.com>2016-12-10 01:13:20 -0300
committerJuan Linietsky <reduzio@gmail.com>2016-12-10 01:13:20 -0300
commit22a90e8f2acce60f92958788a52b3f0bdb1a0cdf (patch)
treef6e0a7282992c9adf3e1c929d2462ae921bcd461
parent18ebd22000478dffc91255e89b9845f74b05b606 (diff)
DOF blur, near and far fields..
-rw-r--r--core/math/camera_matrix.cpp2
-rw-r--r--core/math/camera_matrix.h2
-rw-r--r--drivers/gles3/rasterizer_scene_gles3.cpp196
-rw-r--r--drivers/gles3/rasterizer_scene_gles3.h31
-rw-r--r--drivers/gles3/shaders/effect_blur.glsl177
-rw-r--r--drivers/gles3/shaders/tonemap.glsl99
-rw-r--r--scene/resources/environment.cpp198
-rw-r--r--scene/resources/environment.h53
-rw-r--r--servers/visual/rasterizer.h4
-rw-r--r--servers/visual/visual_server_raster.h5
-rw-r--r--servers/visual_server.h11
11 files changed, 731 insertions, 47 deletions
diff --git a/core/math/camera_matrix.cpp b/core/math/camera_matrix.cpp
index fc35908fa3..89f3ee1add 100644
--- a/core/math/camera_matrix.cpp
+++ b/core/math/camera_matrix.cpp
@@ -54,7 +54,7 @@ void CameraMatrix::set_zero() {
}
-Plane CameraMatrix::xform4(const Plane& p_vec4) {
+Plane CameraMatrix::xform4(const Plane& p_vec4) const {
Plane ret;
diff --git a/core/math/camera_matrix.h b/core/math/camera_matrix.h
index 7fcff63768..c597ec4034 100644
--- a/core/math/camera_matrix.h
+++ b/core/math/camera_matrix.h
@@ -80,7 +80,7 @@ struct CameraMatrix {
CameraMatrix operator*(const CameraMatrix& p_matrix) const;
- Plane xform4(const Plane& p_vec4);
+ Plane xform4(const Plane& p_vec4) const;
_FORCE_INLINE_ Vector3 xform(const Vector3& p_vec3) const;
operator String() const;
diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp
index ec304e7a46..2c6c9dd9ba 100644
--- a/drivers/gles3/rasterizer_scene_gles3.cpp
+++ b/drivers/gles3/rasterizer_scene_gles3.cpp
@@ -850,7 +850,36 @@ void RasterizerSceneGLES3::environment_set_ambient_light(RID p_env, const Color&
}
-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) {
+
+
+void RasterizerSceneGLES3::environment_set_dof_blur_far(RID p_env,bool p_enable,float p_distance,float p_transition,float p_amount,VS::EnvironmentDOFBlurQuality p_quality){
+
+ Environment *env=environment_owner.getornull(p_env);
+ ERR_FAIL_COND(!env);
+
+ env->dof_blur_far_enabled=p_enable;
+ env->dof_blur_far_distance=p_distance;
+ env->dof_blur_far_transition=p_transition;
+ env->dof_blur_far_amount=p_amount;
+ env->dof_blur_far_quality=p_quality;
+
+
+}
+
+void RasterizerSceneGLES3::environment_set_dof_blur_near(RID p_env,bool p_enable,float p_distance,float p_transition,float p_amount,VS::EnvironmentDOFBlurQuality p_quality){
+
+ Environment *env=environment_owner.getornull(p_env);
+ ERR_FAIL_COND(!env);
+
+ env->dof_blur_near_enabled=p_enable;
+ env->dof_blur_near_distance=p_distance;
+ env->dof_blur_near_transition=p_transition;
+ env->dof_blur_near_amount=p_amount;
+ 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_treshold, VS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_treshold, float p_hdr_bleed_scale, bool p_bicubic_upscale) {
Environment *env=environment_owner.getornull(p_env);
ERR_FAIL_COND(!env);
@@ -863,6 +892,7 @@ void RasterizerSceneGLES3::environment_set_glow(RID p_env,bool p_enable,int p_le
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;
+ env->glow_bicubic_upscale=p_bicubic_upscale;
}
void RasterizerSceneGLES3::environment_set_fog(RID p_env,bool p_enable,float p_begin,float p_end,RID p_gradient_texture){
@@ -3035,7 +3065,7 @@ void RasterizerSceneGLES3::_render_mrts(Environment *env,const CameraMatrix &p_c
}
-void RasterizerSceneGLES3::_post_process(Environment *env){
+void RasterizerSceneGLES3::_post_process(Environment *env,const CameraMatrix &p_cam_projection){
//copy to front buffer
@@ -3077,6 +3107,157 @@ void RasterizerSceneGLES3::_post_process(Environment *env){
GLuint composite_from = storage->frame.current_rt->buffers.diffuse;
+ if (env->dof_blur_far_enabled) {
+
+ //blur diffuse into effect mipmaps using separatable convolution
+ //storage->shaders.copy.set_conditional(CopyShaderGLES3::GAUSSIAN_HORIZONTAL,true);
+
+ int vp_h = storage->frame.current_rt->height;
+ int vp_w = storage->frame.current_rt->width;
+
+ state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::DOF_FAR_BLUR,true);
+ state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::DOF_QUALITY_LOW,env->dof_blur_far_quality==VS::ENV_DOF_BLUR_QUALITY_LOW);
+ state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::DOF_QUALITY_MEDIUM,env->dof_blur_far_quality==VS::ENV_DOF_BLUR_QUALITY_MEDIUM);
+ state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::DOF_QUALITY_HIGH,env->dof_blur_far_quality==VS::ENV_DOF_BLUR_QUALITY_HIGH);
+
+ state.effect_blur_shader.bind();
+ int qsteps[3]={4,10,20};
+
+ float radius = (env->dof_blur_far_amount*env->dof_blur_far_amount) / qsteps[env->dof_blur_far_quality];
+
+ state.effect_blur_shader.set_uniform(EffectBlurShaderGLES3::DOF_BEGIN,env->dof_blur_far_distance);
+ state.effect_blur_shader.set_uniform(EffectBlurShaderGLES3::DOF_END,env->dof_blur_far_distance+env->dof_blur_far_transition);
+ state.effect_blur_shader.set_uniform(EffectBlurShaderGLES3::DOF_DIR,Vector2(1,0));
+ state.effect_blur_shader.set_uniform(EffectBlurShaderGLES3::DOF_RADIUS,radius);
+ 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::CAMERA_Z_NEAR,p_cam_projection.get_z_near());
+ state.effect_blur_shader.set_uniform(EffectBlurShaderGLES3::CAMERA_Z_FAR,p_cam_projection.get_z_far());
+
+ glActiveTexture(GL_TEXTURE1);
+ glBindTexture(GL_TEXTURE_2D,storage->frame.current_rt->depth);
+
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D,composite_from);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+ glBindFramebuffer(GL_FRAMEBUFFER,storage->frame.current_rt->fbo); //copy to front first
+
+ _copy_screen();
+
+
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D,storage->frame.current_rt->color);
+ state.effect_blur_shader.set_uniform(EffectBlurShaderGLES3::DOF_DIR,Vector2(0,1));
+ glBindFramebuffer(GL_FRAMEBUFFER,storage->frame.current_rt->effects.mip_maps[0].sizes[0].fbo); // copy to base level
+ _copy_screen();
+
+ state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::DOF_FAR_BLUR,false);
+ state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::DOF_FAR_BLUR,false);
+ state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::DOF_QUALITY_LOW,false);
+ state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::DOF_QUALITY_MEDIUM,false);
+ state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::DOF_QUALITY_HIGH,false);
+
+
+ composite_from=storage->frame.current_rt->effects.mip_maps[0].color;
+
+ }
+
+ if (env->dof_blur_near_enabled) {
+
+ //blur diffuse into effect mipmaps using separatable convolution
+ //storage->shaders.copy.set_conditional(CopyShaderGLES3::GAUSSIAN_HORIZONTAL,true);
+
+ int vp_h = storage->frame.current_rt->height;
+ int vp_w = storage->frame.current_rt->width;
+
+ state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::DOF_NEAR_BLUR,true);
+ state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::DOF_NEAR_FIRST_TAP,true);
+
+ state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::DOF_QUALITY_LOW,env->dof_blur_near_quality==VS::ENV_DOF_BLUR_QUALITY_LOW);
+ state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::DOF_QUALITY_MEDIUM,env->dof_blur_near_quality==VS::ENV_DOF_BLUR_QUALITY_MEDIUM);
+ state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::DOF_QUALITY_HIGH,env->dof_blur_near_quality==VS::ENV_DOF_BLUR_QUALITY_HIGH);
+
+ state.effect_blur_shader.bind();
+ int qsteps[3]={4,10,20};
+
+ float radius = (env->dof_blur_near_amount*env->dof_blur_near_amount) / qsteps[env->dof_blur_near_quality];
+
+ state.effect_blur_shader.set_uniform(EffectBlurShaderGLES3::DOF_BEGIN,env->dof_blur_near_distance);
+ state.effect_blur_shader.set_uniform(EffectBlurShaderGLES3::DOF_END,env->dof_blur_near_distance-env->dof_blur_near_transition);
+ state.effect_blur_shader.set_uniform(EffectBlurShaderGLES3::DOF_DIR,Vector2(1,0));
+ state.effect_blur_shader.set_uniform(EffectBlurShaderGLES3::DOF_RADIUS,radius);
+ 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::CAMERA_Z_NEAR,p_cam_projection.get_z_near());
+ state.effect_blur_shader.set_uniform(EffectBlurShaderGLES3::CAMERA_Z_FAR,p_cam_projection.get_z_far());
+
+ glActiveTexture(GL_TEXTURE1);
+ glBindTexture(GL_TEXTURE_2D,storage->frame.current_rt->depth);
+
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D,composite_from);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+ glBindFramebuffer(GL_FRAMEBUFFER,storage->frame.current_rt->fbo); //copy to front first
+
+ _copy_screen();
+ //manually do the blend if this is the first operation resolving from the diffuse buffer
+ state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::DOF_NEAR_BLUR_MERGE,composite_from == storage->frame.current_rt->buffers.diffuse);
+ state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::DOF_NEAR_FIRST_TAP,false);
+ state.effect_blur_shader.bind();
+
+
+
+ state.effect_blur_shader.set_uniform(EffectBlurShaderGLES3::DOF_BEGIN,env->dof_blur_near_distance);
+ state.effect_blur_shader.set_uniform(EffectBlurShaderGLES3::DOF_END,env->dof_blur_near_distance-env->dof_blur_near_transition);
+ state.effect_blur_shader.set_uniform(EffectBlurShaderGLES3::DOF_DIR,Vector2(0,1));
+ state.effect_blur_shader.set_uniform(EffectBlurShaderGLES3::DOF_RADIUS,radius);
+ 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::CAMERA_Z_NEAR,p_cam_projection.get_z_near());
+ state.effect_blur_shader.set_uniform(EffectBlurShaderGLES3::CAMERA_Z_FAR,p_cam_projection.get_z_far());
+
+
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D,storage->frame.current_rt->color);
+
+ glBindFramebuffer(GL_FRAMEBUFFER,storage->frame.current_rt->effects.mip_maps[0].sizes[0].fbo); // copy to base level
+
+ if (composite_from != storage->frame.current_rt->buffers.diffuse) {
+
+ glEnable(GL_BLEND);
+ glBlendEquation(GL_FUNC_ADD);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ } else {
+ glActiveTexture(GL_TEXTURE2);
+ glBindTexture(GL_TEXTURE_2D,storage->frame.current_rt->buffers.diffuse);
+
+ }
+
+ _copy_screen();
+
+ if (composite_from != storage->frame.current_rt->buffers.diffuse) {
+
+ glDisable(GL_BLEND);
+ }
+
+ state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::DOF_NEAR_BLUR,false);
+ state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::DOF_NEAR_FIRST_TAP,false);
+ state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::DOF_NEAR_BLUR_MERGE,false);
+ state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::DOF_QUALITY_LOW,false);
+ state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::DOF_QUALITY_MEDIUM,false);
+ state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::DOF_QUALITY_HIGH,false);
+
+
+ composite_from=storage->frame.current_rt->effects.mip_maps[0].color;
+
+ }
+
if ( env->auto_exposure) {
//compute auto exposure
@@ -3266,6 +3447,7 @@ void RasterizerSceneGLES3::_post_process(Environment *env){
state.tonemap_shader.set_conditional(TonemapShaderGLES3::USE_REINDHART_TONEMAPPER,env->tone_mapper==VS::ENV_TONE_MAPPER_REINHARDT);
state.tonemap_shader.set_conditional(TonemapShaderGLES3::USE_AUTO_EXPOSURE,env->auto_exposure);
+ state.tonemap_shader.set_conditional(TonemapShaderGLES3::USE_GLOW_FILTER_BICUBIC,env->glow_bicubic_upscale);
@@ -3315,6 +3497,12 @@ void RasterizerSceneGLES3::_post_process(Environment *env){
if (max_glow_level>=0) {
state.tonemap_shader.set_uniform(TonemapShaderGLES3::GLOW_INTENSITY,env->glow_intensity);
+ int ss[2]={
+ storage->frame.current_rt->width,
+ storage->frame.current_rt->height,
+ };
+ glUniform2iv(state.tonemap_shader.get_uniform(TonemapShaderGLES3::GLOW_TEXTURE_SIZE),1,ss);
+
}
if (env->auto_exposure) {
@@ -3344,6 +3532,8 @@ void RasterizerSceneGLES3::_post_process(Environment *env){
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);
+ state.tonemap_shader.set_conditional(TonemapShaderGLES3::USE_GLOW_FILTER_BICUBIC,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){
@@ -3605,7 +3795,7 @@ void RasterizerSceneGLES3::render_scene(const Transform& p_cam_transform,const C
}
- _post_process(env);
+ _post_process(env,p_cam_projection);
if (false && shadow_atlas) {
diff --git a/drivers/gles3/rasterizer_scene_gles3.h b/drivers/gles3/rasterizer_scene_gles3.h
index 6ca4529ed9..78e8b3e477 100644
--- a/drivers/gles3/rasterizer_scene_gles3.h
+++ b/drivers/gles3/rasterizer_scene_gles3.h
@@ -349,6 +349,7 @@ public:
VS::EnvironmentGlowBlendMode glow_blend_mode;
float glow_hdr_bleed_treshold;
float glow_hdr_bleed_scale;
+ bool glow_bicubic_upscale;
VS::EnvironmentToneMapper tone_mapper;
float tone_mapper_exposure;
@@ -359,6 +360,17 @@ public:
float auto_exposure_max;
float auto_exposure_grey;
+ bool dof_blur_far_enabled;
+ float dof_blur_far_distance;
+ float dof_blur_far_transition;
+ float dof_blur_far_amount;
+ VS::EnvironmentDOFBlurQuality dof_blur_far_quality;
+
+ bool dof_blur_near_enabled;
+ float dof_blur_near_distance;
+ float dof_blur_near_transition;
+ float dof_blur_near_amount;
+ VS::EnvironmentDOFBlurQuality dof_blur_near_quality;
Environment() {
bg_mode=VS::ENV_BG_CLEAR_COLOR;
@@ -403,7 +415,19 @@ public:
glow_blend_mode=VS::GLOW_BLEND_MODE_SOFTLIGHT;
glow_hdr_bleed_treshold=1.0;
glow_hdr_bleed_scale=2.0;
+ glow_bicubic_upscale=false;
+
+ dof_blur_far_enabled=false;
+ dof_blur_far_distance=10;
+ dof_blur_far_transition=5;
+ dof_blur_far_amount=0.1;
+ dof_blur_far_quality=VS::ENV_DOF_BLUR_QUALITY_MEDIUM;
+ dof_blur_near_enabled=false;
+ dof_blur_near_distance=2;
+ dof_blur_near_transition=1;
+ dof_blur_near_amount=0.1;
+ dof_blur_near_quality=VS::ENV_DOF_BLUR_QUALITY_MEDIUM;
}
};
@@ -420,12 +444,15 @@ 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_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_dof_blur_near(RID p_env,bool p_enable,float p_distance,float p_transition,float p_far_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_far_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_treshold,VS::EnvironmentGlowBlendMode p_blend_mode,float p_hdr_bleed_treshold,float p_hdr_bleed_scale,bool p_bicubic_upscale);
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);
virtual void environment_set_ssao(RID p_env,bool p_enable, float p_radius, float p_radius2, float p_intensity2, float p_intensity, float p_bias, float p_light_affect,const Color &p_color,bool p_blur);
+
virtual void environment_set_tonemap(RID p_env,VS::EnvironmentToneMapper p_tone_mapper,float p_exposure,float p_white,bool p_auto_exposure,float p_min_luminance,float p_max_luminance,float p_auto_exp_speed,float p_auto_exp_scale);
virtual void environment_set_adjustment(RID p_env,bool p_enable,float p_brightness,float p_contrast,float p_saturation,RID p_ramp);
@@ -663,7 +690,7 @@ public:
void _fill_render_list(InstanceBase** p_cull_result,int p_cull_count,bool p_shadow);
void _render_mrts(Environment *env, const CameraMatrix &p_cam_projection);
- void _post_process(Environment *env);
+ void _post_process(Environment *env, const CameraMatrix &p_cam_projection);
virtual void 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);
virtual void render_shadow(RID p_light,RID p_shadow_atlas,int p_pass,InstanceBase** p_cull_result,int p_cull_count);
diff --git a/drivers/gles3/shaders/effect_blur.glsl b/drivers/gles3/shaders/effect_blur.glsl
index 589af64d44..89afa12f60 100644
--- a/drivers/gles3/shaders/effect_blur.glsl
+++ b/drivers/gles3/shaders/effect_blur.glsl
@@ -41,6 +41,40 @@ uniform float glow_strength;
#endif
+#if defined(DOF_FAR_BLUR) || defined (DOF_NEAR_BLUR)
+
+#ifdef DOF_QUALITY_LOW
+const int dof_kernel_size=5;
+const int dof_kernel_from=2;
+const float dof_kernel[5] = float[] (0.153388,0.221461,0.250301,0.221461,0.153388);
+#endif
+
+#ifdef DOF_QUALITY_MEDIUM
+const int dof_kernel_size=11;
+const int dof_kernel_from=5;
+const float dof_kernel[11] = float[] (0.055037,0.072806,0.090506,0.105726,0.116061,0.119726,0.116061,0.105726,0.090506,0.072806,0.055037);
+
+#endif
+
+#ifdef DOF_QUALITY_HIGH
+const int dof_kernel_size=21;
+const int dof_kernel_from=10;
+const float dof_kernel[21] = float[] (0.028174,0.032676,0.037311,0.041944,0.046421,0.050582,0.054261,0.057307,0.059587,0.060998,0.061476,0.060998,0.059587,0.057307,0.054261,0.050582,0.046421,0.041944,0.037311,0.032676,0.028174);
+#endif
+
+uniform sampler2D dof_source_depth; //texunit:1
+uniform float dof_begin;
+uniform float dof_end;
+uniform vec2 dof_dir;
+uniform float dof_radius;
+
+#ifdef DOF_NEAR_BLUR_MERGE
+
+uniform sampler2D source_dof_original; //texunit:2
+#endif
+
+#endif
+
#ifdef GLOW_FIRST_PASS
@@ -60,16 +94,23 @@ uniform float glow_hdr_scale;
#endif
+uniform float camera_z_far;
+uniform float camera_z_near;
+
void main() {
#ifdef GAUSSIAN_HORIZONTAL
- vec4 color =textureLod( source_color, uv_interp+vec2( 0.0, 0.0)*pixel_size,lod )*0.38774;
- color+=textureLod( source_color, uv_interp+vec2( 1.0, 0.0)*pixel_size,lod )*0.24477;
- color+=textureLod( source_color, uv_interp+vec2( 2.0, 0.0)*pixel_size,lod )*0.06136;
- color+=textureLod( source_color, uv_interp+vec2(-1.0, 0.0)*pixel_size,lod )*0.24477;
- color+=textureLod( source_color, uv_interp+vec2(-2.0, 0.0)*pixel_size,lod )*0.06136;
+ vec2 pix_size = pixel_size;
+ pix_size*=0.5; //reading from larger buffer, so use more samples
+ vec4 color =textureLod( source_color, uv_interp+vec2( 0.0, 0.0)*pix_size,lod )*0.214607;
+ color+=textureLod( source_color, uv_interp+vec2( 1.0, 0.0)*pix_size,lod )*0.189879;
+ color+=textureLod( source_color, uv_interp+vec2( 2.0, 0.0)*pix_size,lod )*0.157305;
+ color+=textureLod( source_color, uv_interp+vec2( 3.0, 0.0)*pix_size,lod )*0.071303;
+ color+=textureLod( source_color, uv_interp+vec2(-1.0, 0.0)*pix_size,lod )*0.189879;
+ color+=textureLod( source_color, uv_interp+vec2(-2.0, 0.0)*pix_size,lod )*0.157305;
+ color+=textureLod( source_color, uv_interp+vec2(-3.0, 0.0)*pix_size,lod )*0.071303;
frag_color = color;
#endif
@@ -82,32 +123,126 @@ void main() {
frag_color = color;
#endif
-
+//glow uses larger sigma for a more rounded blur effect
#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;
+ vec2 pix_size = pixel_size;
+ pix_size*=0.5; //reading from larger buffer, so use more samples
+ 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;
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;
+ vec4 color =textureLod( source_color, uv_interp+vec2(0.0, 0.0)*pixel_size,lod )*0.288713;
+ color+=textureLod( source_color, uv_interp+vec2(0.0, 1.0)*pixel_size,lod )*0.233062;
+ color+=textureLod( source_color, uv_interp+vec2(0.0, 2.0)*pixel_size,lod )*0.122581;
+ color+=textureLod( source_color, uv_interp+vec2(0.0,-1.0)*pixel_size,lod )*0.233062;
+ color+=textureLod( source_color, uv_interp+vec2(0.0,-2.0)*pixel_size,lod )*0.122581;
color*=glow_strength;
frag_color = color;
#endif
+#ifdef DOF_FAR_BLUR
+
+ vec4 color_accum = vec4(0.0);
+
+ float depth = textureLod( dof_source_depth, uv_interp, 0.0).r;
+ depth = depth * 2.0 - 1.0;
+ depth = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - depth * (camera_z_far - camera_z_near));
+
+ float amount = smoothstep(dof_begin,dof_end,depth);
+ float k_accum=0.0;
+
+ for(int i=0;i<dof_kernel_size;i++) {
+
+ int int_ofs = i-dof_kernel_from;
+ vec2 tap_uv = uv_interp + dof_dir * float(int_ofs) * amount * dof_radius;
+
+ float tap_k = dof_kernel[i];
+
+ float tap_depth = texture( dof_source_depth, tap_uv, 0.0).r;
+ tap_depth = tap_depth * 2.0 - 1.0;
+ tap_depth = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - tap_depth * (camera_z_far - camera_z_near));
+
+ float tap_amount = mix(smoothstep(dof_begin,dof_end,tap_depth),1.0,int_ofs==0);
+ tap_amount*=tap_amount*tap_amount; //prevent undesired glow effect
+
+ vec4 tap_color = textureLod( source_color, tap_uv, 0.0) * tap_k;
+
+ k_accum+=tap_k*tap_amount;
+ color_accum+=tap_color*tap_amount;
+
+
+ }
+
+ if (k_accum>0.0) {
+ color_accum/=k_accum;
+ }
+
+ frag_color = color_accum;///k_accum;
+
+#endif
+
+#ifdef DOF_NEAR_BLUR
+
+ vec4 color_accum = vec4(0.0);
+
+ float max_accum=0;
+
+ for(int i=0;i<dof_kernel_size;i++) {
+
+ int int_ofs = i-dof_kernel_from;
+ vec2 tap_uv = uv_interp + dof_dir * float(int_ofs) * dof_radius;
+ float ofs_influence = max(0.0,1.0-float(abs(int_ofs))/float(dof_kernel_from));
+
+ float tap_k = dof_kernel[i];
+
+ vec4 tap_color = textureLod( source_color, tap_uv, 0.0);
+
+ float tap_depth = texture( dof_source_depth, tap_uv, 0.0).r;
+ tap_depth = tap_depth * 2.0 - 1.0;
+ tap_depth = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - tap_depth * (camera_z_far - camera_z_near));
+ float tap_amount = 1.0-smoothstep(dof_end,dof_begin,tap_depth);
+ tap_amount*=tap_amount*tap_amount; //prevent undesired glow effect
+
+#ifdef DOF_NEAR_FIRST_TAP
+
+ tap_color.a= 1.0-smoothstep(dof_end,dof_begin,tap_depth);
+
+#endif
+
+ max_accum=max(max_accum,tap_amount*ofs_influence);
+
+ color_accum+=tap_color*tap_k;
+
+ }
+
+ color_accum.a=max(color_accum.a,sqrt(max_accum));
+
+
+#ifdef DOF_NEAR_BLUR_MERGE
+
+ vec4 original = textureLod( source_dof_original, uv_interp, 0.0);
+ color_accum = mix(original,color_accum,color_accum.a);
+
+#endif
+
+#ifndef DOF_NEAR_FIRST_TAP
+ //color_accum=vec4(vec3(color_accum.a),1.0);
+#endif
+ frag_color = color_accum;
+
+#endif
+
+
+
#ifdef GLOW_FIRST_PASS
#ifdef GLOW_USE_AUTO_EXPOSURE
@@ -137,5 +272,7 @@ void main() {
frag_color = vec4( mix(color.rgb,color.rgb*mix(ssao_color.rgb,vec3(1.0),ssao),color.a), 1.0 );
#endif
+
+
}
diff --git a/drivers/gles3/shaders/tonemap.glsl b/drivers/gles3/shaders/tonemap.glsl
index 8ee51e9d0c..8f7e0c7be3 100644
--- a/drivers/gles3/shaders/tonemap.glsl
+++ b/drivers/gles3/shaders/tonemap.glsl
@@ -41,6 +41,90 @@ uniform highp float glow_intensity;
layout(location = 0) out vec4 frag_color;
+#ifdef USE_GLOW_FILTER_BICUBIC
+
+// w0, w1, w2, and w3 are the four cubic B-spline basis functions
+float w0(float a)
+{
+ return (1.0/6.0)*(a*(a*(-a + 3.0) - 3.0) + 1.0);
+}
+
+float w1(float a)
+{
+ return (1.0/6.0)*(a*a*(3.0*a - 6.0) + 4.0);
+}
+
+float w2(float a)
+{
+ return (1.0/6.0)*(a*(a*(-3.0*a + 3.0) + 3.0) + 1.0);
+}
+
+float w3(float a)
+{
+ return (1.0/6.0)*(a*a*a);
+}
+
+// g0 and g1 are the two amplitude functions
+float g0(float a)
+{
+ return w0(a) + w1(a);
+}
+
+float g1(float a)
+{
+ return w2(a) + w3(a);
+}
+
+// h0 and h1 are the two offset functions
+float h0(float a)
+{
+ return -1.0 + w1(a) / (w0(a) + w1(a));
+}
+
+float h1(float a)
+{
+ return 1.0 + w3(a) / (w2(a) + w3(a));
+}
+
+uniform ivec2 glow_texture_size;
+
+vec4 texture2D_bicubic(sampler2D tex, vec2 uv,int p_lod)
+{
+ float lod=float(p_lod);
+ vec2 tex_size = vec2(glow_texture_size >> p_lod);
+ vec2 pixel_size =1.0/tex_size;
+ uv = uv*tex_size + 0.5;
+ vec2 iuv = floor( uv );
+ vec2 fuv = fract( uv );
+
+ float g0x = g0(fuv.x);
+ float g1x = g1(fuv.x);
+ float h0x = h0(fuv.x);
+ float h1x = h1(fuv.x);
+ float h0y = h0(fuv.y);
+ float h1y = h1(fuv.y);
+
+ vec2 p0 = (vec2(iuv.x + h0x, iuv.y + h0y) - 0.5) * pixel_size;
+ vec2 p1 = (vec2(iuv.x + h1x, iuv.y + h0y) - 0.5) * pixel_size;
+ vec2 p2 = (vec2(iuv.x + h0x, iuv.y + h1y) - 0.5) * pixel_size;
+ vec2 p3 = (vec2(iuv.x + h1x, iuv.y + h1y) - 0.5) * pixel_size;
+
+ return g0(fuv.y) * (g0x * textureLod(tex, p0,lod) +
+ g1x * textureLod(tex, p1,lod)) +
+ g1(fuv.y) * (g0x * textureLod(tex, p2,lod) +
+ g1x * textureLod(tex, p3,lod));
+}
+
+
+
+#define GLOW_TEXTURE_SAMPLE(m_tex,m_uv,m_lod) texture2D_bicubic(m_tex,m_uv,m_lod)
+
+#else
+
+#define GLOW_TEXTURE_SAMPLE(m_tex,m_uv,m_lod) textureLod(m_tex,m_uv,float(m_lod))
+
+#endif
+
void main() {
@@ -60,31 +144,32 @@ void main() {
vec3 glow = vec3(0.0);
#ifdef USE_GLOW_LEVEL1
- glow+=textureLod(source_glow,uv_interp,1.0).rgb;
+
+ glow+=GLOW_TEXTURE_SAMPLE(source_glow,uv_interp,1).rgb;
#endif
#ifdef USE_GLOW_LEVEL2
- glow+=textureLod(source_glow,uv_interp,2.0).rgb;
+ glow+=GLOW_TEXTURE_SAMPLE(source_glow,uv_interp,2).rgb;
#endif
#ifdef USE_GLOW_LEVEL3
- glow+=textureLod(source_glow,uv_interp,3.0).rgb;
+ glow+=GLOW_TEXTURE_SAMPLE(source_glow,uv_interp,3).rgb;
#endif
#ifdef USE_GLOW_LEVEL4
- glow+=textureLod(source_glow,uv_interp,4.0).rgb;
+ glow+=GLOW_TEXTURE_SAMPLE(source_glow,uv_interp,4).rgb;
#endif
#ifdef USE_GLOW_LEVEL5
- glow+=textureLod(source_glow,uv_interp,5.0).rgb;
+ glow+=GLOW_TEXTURE_SAMPLE(source_glow,uv_interp,5).rgb;
#endif
#ifdef USE_GLOW_LEVEL6
- glow+=textureLod(source_glow,uv_interp,6.0).rgb;
+ glow+=GLOW_TEXTURE_SAMPLE(source_glow,uv_interp,6).rgb;
#endif
#ifdef USE_GLOW_LEVEL7
- glow+=textureLod(source_glow,uv_interp,7.0).rgb;
+ glow+=GLOW_TEXTURE_SAMPLE(source_glow,uv_interp,7).rgb;
#endif
diff --git a/scene/resources/environment.cpp b/scene/resources/environment.cpp
index eb393f2ad1..71a711dc72 100644
--- a/scene/resources/environment.cpp
+++ b/scene/resources/environment.cpp
@@ -477,7 +477,7 @@ bool Environment::is_ssao_blur_enabled() const {
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);
+ 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,glow_bicubic_upscale);
}
bool Environment::is_glow_enabled() const{
@@ -494,7 +494,7 @@ void Environment::set_glow_level(int p_level,bool p_enabled){
else
glow_levels&=~(1<<p_level);
- 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);
+ 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,glow_bicubic_upscale);
}
bool Environment::is_glow_level_enabled(int p_level) const{
@@ -508,7 +508,7 @@ void Environment::set_glow_intensity(float p_intensity){
glow_intensity=p_intensity;
- 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);
+ 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,glow_bicubic_upscale);
}
float Environment::get_glow_intensity() const{
@@ -519,7 +519,7 @@ float Environment::get_glow_intensity() const{
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);
+ 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,glow_bicubic_upscale);
}
float Environment::get_glow_strength() const{
@@ -531,7 +531,7 @@ 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);
+ 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,glow_bicubic_upscale);
}
float Environment::get_glow_bloom() const{
@@ -543,7 +543,7 @@ 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);
+ 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,glow_bicubic_upscale);
}
Environment::GlowBlendMode Environment::get_glow_blend_mode() const{
@@ -555,7 +555,7 @@ 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);
+ 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,glow_bicubic_upscale);
}
float Environment::get_glow_hdr_bleed_treshold() const{
@@ -567,7 +567,7 @@ 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);
+ 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,glow_bicubic_upscale);
}
float Environment::get_glow_hdr_bleed_scale() const{
@@ -575,7 +575,128 @@ float Environment::get_glow_hdr_bleed_scale() const{
return glow_hdr_bleed_scale;
}
+void Environment::set_glow_bicubic_upscale(bool p_enable) {
+ glow_bicubic_upscale=p_enable;
+ 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,glow_bicubic_upscale);
+
+}
+
+bool Environment::is_glow_bicubic_upscale_enabled() const {
+
+ return glow_bicubic_upscale;
+}
+
+
+void Environment::set_dof_blur_far_enabled(bool p_enable) {
+
+ dof_blur_far_enabled=p_enable;
+ VS::get_singleton()->environment_set_dof_blur_far(environment,dof_blur_far_enabled,dof_blur_far_distance,dof_blur_far_transition,dof_blur_far_amount,VS::EnvironmentDOFBlurQuality(dof_blur_far_quality));
+}
+
+bool Environment::is_dof_blur_far_enabled() const{
+
+ return dof_blur_far_enabled;
+}
+
+void Environment::set_dof_blur_far_distance(float p_distance){
+
+ dof_blur_far_distance=p_distance;
+ VS::get_singleton()->environment_set_dof_blur_far(environment,dof_blur_far_enabled,dof_blur_far_distance,dof_blur_far_transition,dof_blur_far_amount,VS::EnvironmentDOFBlurQuality(dof_blur_far_quality));
+
+}
+float Environment::get_dof_blur_far_distance() const{
+
+ return dof_blur_far_distance;
+}
+
+void Environment::set_dof_blur_far_transition(float p_distance){
+
+ dof_blur_far_transition=p_distance;
+ VS::get_singleton()->environment_set_dof_blur_far(environment,dof_blur_far_enabled,dof_blur_far_distance,dof_blur_far_transition,dof_blur_far_amount,VS::EnvironmentDOFBlurQuality(dof_blur_far_quality));
+}
+float Environment::get_dof_blur_far_transition() const{
+
+ return dof_blur_far_transition;
+}
+
+void Environment::set_dof_blur_far_amount(float p_amount){
+
+ dof_blur_far_amount=p_amount;
+ VS::get_singleton()->environment_set_dof_blur_far(environment,dof_blur_far_enabled,dof_blur_far_distance,dof_blur_far_transition,dof_blur_far_amount,VS::EnvironmentDOFBlurQuality(dof_blur_far_quality));
+
+}
+float Environment::get_dof_blur_far_amount() const{
+
+ return dof_blur_far_amount;
+}
+
+void Environment::set_dof_blur_far_quality(DOFBlurQuality p_quality) {
+
+ dof_blur_far_quality=p_quality;
+ VS::get_singleton()->environment_set_dof_blur_far(environment,dof_blur_far_enabled,dof_blur_far_distance,dof_blur_far_transition,dof_blur_far_amount,VS::EnvironmentDOFBlurQuality(dof_blur_far_quality));
+}
+
+Environment::DOFBlurQuality Environment::get_dof_blur_far_quality() const {
+
+ return dof_blur_far_quality;
+}
+
+
+void Environment::set_dof_blur_near_enabled(bool p_enable) {
+
+ dof_blur_near_enabled=p_enable;
+ VS::get_singleton()->environment_set_dof_blur_near(environment,dof_blur_near_enabled,dof_blur_near_distance,dof_blur_near_transition,dof_blur_near_amount,VS::EnvironmentDOFBlurQuality(dof_blur_near_quality));
+}
+
+bool Environment::is_dof_blur_near_enabled() const{
+
+ return dof_blur_near_enabled;
+}
+
+void Environment::set_dof_blur_near_distance(float p_distance){
+
+ dof_blur_near_distance=p_distance;
+ VS::get_singleton()->environment_set_dof_blur_near(environment,dof_blur_near_enabled,dof_blur_near_distance,dof_blur_near_transition,dof_blur_near_amount,VS::EnvironmentDOFBlurQuality(dof_blur_near_quality));
+}
+
+float Environment::get_dof_blur_near_distance() const{
+
+ return dof_blur_near_distance;
+}
+
+void Environment::set_dof_blur_near_transition(float p_distance){
+
+ dof_blur_near_transition=p_distance;
+ VS::get_singleton()->environment_set_dof_blur_near(environment,dof_blur_near_enabled,dof_blur_near_distance,dof_blur_near_transition,dof_blur_near_amount,VS::EnvironmentDOFBlurQuality(dof_blur_near_quality));
+}
+
+float Environment::get_dof_blur_near_transition() const{
+
+ return dof_blur_near_transition;
+}
+
+void Environment::set_dof_blur_near_amount(float p_amount){
+
+ dof_blur_near_amount=p_amount;
+ VS::get_singleton()->environment_set_dof_blur_near(environment,dof_blur_near_enabled,dof_blur_near_distance,dof_blur_near_transition,dof_blur_near_amount,VS::EnvironmentDOFBlurQuality(dof_blur_near_quality));
+}
+
+float Environment::get_dof_blur_near_amount() const{
+
+ return dof_blur_near_amount;
+}
+
+void Environment::set_dof_blur_near_quality(DOFBlurQuality p_quality) {
+
+ dof_blur_near_quality=p_quality;
+ VS::get_singleton()->environment_set_dof_blur_near(environment,dof_blur_near_enabled,dof_blur_near_distance,dof_blur_near_transition,dof_blur_near_amount,VS::EnvironmentDOFBlurQuality(dof_blur_near_quality));
+}
+
+Environment::DOFBlurQuality Environment::get_dof_blur_near_quality() const {
+
+ return dof_blur_near_quality;
+}
void Environment::_bind_methods() {
@@ -679,6 +800,48 @@ void Environment::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::COLOR,"ambient_occlusion/color",PROPERTY_HINT_COLOR_NO_ALPHA),_SCS("set_ssao_color"),_SCS("get_ssao_color") );
ADD_PROPERTY(PropertyInfo(Variant::BOOL,"ambient_occlusion/blur"),_SCS("set_ssao_blur"),_SCS("is_ssao_blur_enabled") );
+ ObjectTypeDB::bind_method(_MD("set_dof_blur_far_enabled","enabled"),&Environment::set_dof_blur_far_enabled);
+ ObjectTypeDB::bind_method(_MD("is_dof_blur_far_enabled"),&Environment::is_dof_blur_far_enabled);
+
+ ObjectTypeDB::bind_method(_MD("set_dof_blur_far_distance","intensity"),&Environment::set_dof_blur_far_distance);
+ ObjectTypeDB::bind_method(_MD("get_dof_blur_far_distance"),&Environment::get_dof_blur_far_distance);
+
+ ObjectTypeDB::bind_method(_MD("set_dof_blur_far_transition","intensity"),&Environment::set_dof_blur_far_transition);
+ ObjectTypeDB::bind_method(_MD("get_dof_blur_far_transition"),&Environment::get_dof_blur_far_transition);
+
+ ObjectTypeDB::bind_method(_MD("set_dof_blur_far_amount","intensity"),&Environment::set_dof_blur_far_amount);
+ ObjectTypeDB::bind_method(_MD("get_dof_blur_far_amount"),&Environment::get_dof_blur_far_amount);
+
+ ObjectTypeDB::bind_method(_MD("set_dof_blur_far_quality","intensity"),&Environment::set_dof_blur_far_quality);
+ ObjectTypeDB::bind_method(_MD("get_dof_blur_far_quality"),&Environment::get_dof_blur_far_quality);
+
+ ObjectTypeDB::bind_method(_MD("set_dof_blur_near_enabled","enabled"),&Environment::set_dof_blur_near_enabled);
+ ObjectTypeDB::bind_method(_MD("is_dof_blur_near_enabled"),&Environment::is_dof_blur_near_enabled);
+
+ ObjectTypeDB::bind_method(_MD("set_dof_blur_near_distance","intensity"),&Environment::set_dof_blur_near_distance);
+ ObjectTypeDB::bind_method(_MD("get_dof_blur_near_distance"),&Environment::get_dof_blur_near_distance);
+
+ ObjectTypeDB::bind_method(_MD("set_dof_blur_near_transition","intensity"),&Environment::set_dof_blur_near_transition);
+ ObjectTypeDB::bind_method(_MD("get_dof_blur_near_transition"),&Environment::get_dof_blur_near_transition);
+
+ ObjectTypeDB::bind_method(_MD("set_dof_blur_near_amount","intensity"),&Environment::set_dof_blur_near_amount);
+ ObjectTypeDB::bind_method(_MD("get_dof_blur_near_amount"),&Environment::get_dof_blur_near_amount);
+
+ ObjectTypeDB::bind_method(_MD("set_dof_blur_near_quality","level"),&Environment::set_dof_blur_near_quality);
+ ObjectTypeDB::bind_method(_MD("get_dof_blur_near_quality"),&Environment::get_dof_blur_near_quality);
+
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL,"dof_blur_far/enabled"),_SCS("set_dof_blur_far_enabled"),_SCS("is_dof_blur_far_enabled") );
+ ADD_PROPERTY(PropertyInfo(Variant::REAL,"dof_blur_far/distance",PROPERTY_HINT_EXP_RANGE,"0.01,8192,0.01"),_SCS("set_dof_blur_far_distance"),_SCS("get_dof_blur_far_distance") );
+ ADD_PROPERTY(PropertyInfo(Variant::REAL,"dof_blur_far/transition",PROPERTY_HINT_EXP_RANGE,"0.01,8192,0.01"),_SCS("set_dof_blur_far_transition"),_SCS("get_dof_blur_far_transition") );
+ ADD_PROPERTY(PropertyInfo(Variant::REAL,"dof_blur_far/amount",PROPERTY_HINT_RANGE,"0,1,0.01"),_SCS("set_dof_blur_far_amount"),_SCS("get_dof_blur_far_amount") );
+ ADD_PROPERTY(PropertyInfo(Variant::INT,"dof_blur_far/quality",PROPERTY_HINT_ENUM,"Low,Medium,High"),_SCS("set_dof_blur_far_quality"),_SCS("get_dof_blur_far_quality") );
+
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL,"dof_blur_near/enabled"),_SCS("set_dof_blur_near_enabled"),_SCS("is_dof_blur_near_enabled") );
+ ADD_PROPERTY(PropertyInfo(Variant::REAL,"dof_blur_near/distance",PROPERTY_HINT_EXP_RANGE,"0.01,8192,0.01"),_SCS("set_dof_blur_near_distance"),_SCS("get_dof_blur_near_distance") );
+ ADD_PROPERTY(PropertyInfo(Variant::REAL,"dof_blur_near/transition",PROPERTY_HINT_EXP_RANGE,"0.01,8192,0.01"),_SCS("set_dof_blur_near_transition"),_SCS("get_dof_blur_near_transition") );
+ ADD_PROPERTY(PropertyInfo(Variant::REAL,"dof_blur_near/amount",PROPERTY_HINT_RANGE,"0,1,0.01"),_SCS("set_dof_blur_near_amount"),_SCS("get_dof_blur_near_amount") );
+ ADD_PROPERTY(PropertyInfo(Variant::INT,"dof_blur_near/quality",PROPERTY_HINT_ENUM,"Low,Medium,High"),_SCS("set_dof_blur_near_quality"),_SCS("get_dof_blur_near_quality") );
+
ObjectTypeDB::bind_method(_MD("set_glow_enabled","enabled"),&Environment::set_glow_enabled);
ObjectTypeDB::bind_method(_MD("is_glow_enabled"),&Environment::is_glow_enabled);
@@ -704,6 +867,8 @@ void Environment::_bind_methods() {
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);
+ ObjectTypeDB::bind_method(_MD("set_glow_bicubic_upscale","enabled"),&Environment::set_glow_bicubic_upscale);
+ ObjectTypeDB::bind_method(_MD("is_glow_bicubic_upscale_enabled"),&Environment::is_glow_bicubic_upscale_enabled);
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 );
@@ -720,6 +885,7 @@ void Environment::_bind_methods() {
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") );
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL,"glow/bicubic_upscale"),_SCS("set_glow_bicubic_upscale"),_SCS("is_glow_bicubic_upscale_enabled") );
ObjectTypeDB::bind_method(_MD("set_tonemapper","mode"),&Environment::set_tonemapper);
@@ -795,6 +961,9 @@ void Environment::_bind_methods() {
BIND_CONSTANT(TONE_MAPPER_REINHARDT);
BIND_CONSTANT(TONE_MAPPER_FILMIC);
BIND_CONSTANT(TONE_MAPPER_ACES);
+ BIND_CONSTANT(DOF_BLUR_QUALITY_LOW);
+ BIND_CONSTANT(DOF_BLUR_QUALITY_MEDIUM);
+ BIND_CONSTANT(DOF_BLUR_QUALITY_HIGH);
}
@@ -854,6 +1023,19 @@ Environment::Environment() {
glow_blend_mode=GLOW_BLEND_MODE_SOFTLIGHT;
glow_hdr_bleed_treshold=1.0;
glow_hdr_bleed_scale=2.0;
+ glow_bicubic_upscale=false;
+
+ dof_blur_far_enabled=false;
+ dof_blur_far_distance=10;
+ dof_blur_far_transition=5;
+ dof_blur_far_amount=0.1;
+ dof_blur_far_quality=DOF_BLUR_QUALITY_MEDIUM;
+
+ dof_blur_near_enabled=false;
+ dof_blur_near_distance=2;
+ dof_blur_near_transition=1;
+ dof_blur_near_amount=0.1;
+ dof_blur_near_quality=DOF_BLUR_QUALITY_MEDIUM;
}
diff --git a/scene/resources/environment.h b/scene/resources/environment.h
index 50c48165e8..fcf3e1edc6 100644
--- a/scene/resources/environment.h
+++ b/scene/resources/environment.h
@@ -65,6 +65,11 @@ public:
GLOW_BLEND_MODE_REPLACE,
};
+ enum DOFBlurQuality {
+ DOF_BLUR_QUALITY_LOW,
+ DOF_BLUR_QUALITY_MEDIUM,
+ DOF_BLUR_QUALITY_HIGH,
+ };
private:
RID environment;
@@ -120,7 +125,19 @@ private:
GlowBlendMode glow_blend_mode;
float glow_hdr_bleed_treshold;
float glow_hdr_bleed_scale;
+ bool glow_bicubic_upscale;
+
+ bool dof_blur_far_enabled;
+ float dof_blur_far_distance;
+ float dof_blur_far_transition;
+ float dof_blur_far_amount;
+ DOFBlurQuality dof_blur_far_quality;
+ bool dof_blur_near_enabled;
+ float dof_blur_near_distance;
+ float dof_blur_near_transition;
+ float dof_blur_near_amount;
+ DOFBlurQuality dof_blur_near_quality;
protected:
@@ -199,7 +216,7 @@ public:
void set_ssr_accel(float p_accel);
float get_ssr_accel() const;
- void set_ssr_fade(float p_fade);
+ void set_ssr_fade(float p_transition);
float get_ssr_fade() const;
void set_ssr_depth_tolerance(float p_depth_tolerance);
@@ -263,6 +280,38 @@ public:
void set_glow_hdr_bleed_scale(float p_scale);
float get_glow_hdr_bleed_scale() const;
+ void set_glow_bicubic_upscale(bool p_enable);
+ bool is_glow_bicubic_upscale_enabled() const;
+
+ void set_dof_blur_far_enabled(bool p_enable);
+ bool is_dof_blur_far_enabled() const;
+
+ void set_dof_blur_far_distance(float p_distance);
+ float get_dof_blur_far_distance() const;
+
+ void set_dof_blur_far_transition(float p_distance);
+ float get_dof_blur_far_transition() const;
+
+ void set_dof_blur_far_amount(float p_amount);
+ float get_dof_blur_far_amount() const;
+
+ void set_dof_blur_far_quality(DOFBlurQuality p_quality);
+ DOFBlurQuality get_dof_blur_far_quality() const;
+
+ void set_dof_blur_near_enabled(bool p_enable);
+ bool is_dof_blur_near_enabled() const;
+
+ void set_dof_blur_near_distance(float p_distance);
+ float get_dof_blur_near_distance() const;
+
+ void set_dof_blur_near_transition(float p_distance);
+ float get_dof_blur_near_transition() const;
+
+ void set_dof_blur_near_amount(float p_amount);
+ float get_dof_blur_near_amount() const;
+
+ void set_dof_blur_near_quality(DOFBlurQuality p_quality);
+ DOFBlurQuality get_dof_blur_near_quality() const;
virtual RID get_rid() const;
@@ -277,6 +326,6 @@ public:
VARIANT_ENUM_CAST(Environment::BGMode)
VARIANT_ENUM_CAST(Environment::ToneMapper)
VARIANT_ENUM_CAST(Environment::GlowBlendMode)
-
+VARIANT_ENUM_CAST(Environment::DOFBlurQuality)
#endif // ENVIRONMENT_H
diff --git a/servers/visual/rasterizer.h b/servers/visual/rasterizer.h
index 2b1829283f..228afffdb5 100644
--- a/servers/visual/rasterizer.h
+++ b/servers/visual/rasterizer.h
@@ -61,7 +61,9 @@ 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_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_dof_blur_near(RID p_env,bool p_enable,float p_distance,float p_transition,float p_far_amount,VS::EnvironmentDOFBlurQuality p_quality)=0;
+ virtual 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)=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,bool p_bicubic_upscale)=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 52c156cd6f..78b0e3cadd 100644
--- a/servers/visual/visual_server_raster.h
+++ b/servers/visual/visual_server_raster.h
@@ -879,7 +879,10 @@ public:
BIND10(environment_set_ssao,RID ,bool , float , float , float,float,float , float ,const Color &,bool )
- BIND9(environment_set_glow,RID,bool ,int ,float ,float ,float ,EnvironmentGlowBlendMode,float,float )
+
+ BIND6(environment_set_dof_blur_near,RID,bool ,float,float,float,EnvironmentDOFBlurQuality)
+ BIND6(environment_set_dof_blur_far,RID,bool ,float,float,float,EnvironmentDOFBlurQuality)
+ BIND10(environment_set_glow,RID,bool ,int ,float ,float ,float ,EnvironmentGlowBlendMode,float,float,bool )
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 adc9f4960c..7558fbf818 100644
--- a/servers/visual_server.h
+++ b/servers/visual_server.h
@@ -536,13 +536,22 @@ public:
//set default SSR options
//set default SSSSS options
+ enum EnvironmentDOFBlurQuality {
+ ENV_DOF_BLUR_QUALITY_LOW,
+ ENV_DOF_BLUR_QUALITY_MEDIUM,
+ ENV_DOF_BLUR_QUALITY_HIGH,
+ };
+
+ virtual void environment_set_dof_blur_near(RID p_env,bool p_enable,float p_distance,float p_transition,float p_far_amount,EnvironmentDOFBlurQuality p_quality)=0;
+ virtual void environment_set_dof_blur_far(RID p_env,bool p_enable,float p_distance,float p_transition,float p_far_amount,EnvironmentDOFBlurQuality p_quality)=0;
+
enum EnvironmentGlowBlendMode {
GLOW_BLEND_MODE_ADDITIVE,
GLOW_BLEND_MODE_SCREEN,
GLOW_BLEND_MODE_SOFTLIGHT,
GLOW_BLEND_MODE_REPLACE,
};
- 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_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,bool p_bicubic_upscale)=0;
virtual void environment_set_fog(RID p_env,bool p_enable,float p_begin,float p_end,RID p_gradient_texture)=0;