From 6a5ecfdef1949baaf3597e214ad291b6786f0239 Mon Sep 17 00:00:00 2001 From: Juan Linietsky Date: Thu, 13 Aug 2020 22:07:49 -0300 Subject: [PATCH] Restored fog (non volumetric). Uses a simpler and more intuitive implementation based on density. Its less flexible than before, but its easier to get nice results. --- scene/resources/environment.cpp | 233 +++++------------- scene/resources/environment.h | 64 ++--- servers/rendering/rasterizer.h | 5 +- .../rasterizer_scene_high_end_rd.cpp | 20 +- .../rasterizer_scene_high_end_rd.h | 10 + .../rasterizer_rd/rasterizer_scene_rd.cpp | 51 ++++ .../rasterizer_rd/rasterizer_scene_rd.h | 23 +- .../rasterizer_rd/shaders/scene_high_end.glsl | 42 +++- .../shaders/scene_high_end_inc.glsl | 38 +-- servers/rendering/rendering_server_raster.h | 4 +- servers/rendering/rendering_server_wrap_mt.h | 5 +- servers/rendering_server.cpp | 6 +- servers/rendering_server.h | 4 +- 13 files changed, 231 insertions(+), 274 deletions(-) diff --git a/scene/resources/environment.cpp b/scene/resources/environment.cpp index 526d1013892..a174c3eebeb 100644 --- a/scene/resources/environment.cpp +++ b/scene/resources/environment.cpp @@ -694,150 +694,59 @@ bool Environment::is_fog_enabled() const { return fog_enabled; } -void Environment::set_fog_color(const Color &p_color) { - fog_color = p_color; +void Environment::set_fog_light_color(const Color &p_light_color) { + fog_light_color = p_light_color; _update_fog(); } - -Color Environment::get_fog_color() const { - return fog_color; +Color Environment::get_fog_light_color() const { + return fog_light_color; } - -void Environment::set_fog_sun_color(const Color &p_color) { - fog_sun_color = p_color; +void Environment::set_fog_light_energy(float p_amount) { + fog_light_energy = p_amount; _update_fog(); } - -Color Environment::get_fog_sun_color() const { - return fog_sun_color; +float Environment::get_fog_light_energy() const { + return fog_light_energy; } - -void Environment::set_fog_sun_amount(float p_amount) { - fog_sun_amount = p_amount; +void Environment::set_fog_sun_scatter(float p_amount) { + fog_sun_scatter = p_amount; _update_fog(); } - -float Environment::get_fog_sun_amount() const { - return fog_sun_amount; +float Environment::get_fog_sun_scatter() const { + return fog_sun_scatter; +} +void Environment::set_fog_density(float p_amount) { + fog_density = p_amount; + _update_fog(); +} +float Environment::get_fog_density() const { + return fog_density; +} +void Environment::set_fog_height(float p_amount) { + fog_height = p_amount; + _update_fog(); +} +float Environment::get_fog_height() const { + return fog_height; +} +void Environment::set_fog_height_density(float p_amount) { + fog_height_density = p_amount; + _update_fog(); +} +float Environment::get_fog_height_density() const { + return fog_height_density; } void Environment::_update_fog() { RS::get_singleton()->environment_set_fog( environment, fog_enabled, - fog_color, - fog_sun_color, - fog_sun_amount); -} - -void Environment::set_fog_depth_enabled(bool p_enabled) { - fog_depth_enabled = p_enabled; - _update_fog_depth(); -} - -bool Environment::is_fog_depth_enabled() const { - return fog_depth_enabled; -} - -void Environment::set_fog_depth_begin(float p_distance) { - fog_depth_begin = p_distance; - _update_fog_depth(); -} - -float Environment::get_fog_depth_begin() const { - return fog_depth_begin; -} - -void Environment::set_fog_depth_end(float p_distance) { - fog_depth_end = p_distance; - _update_fog_depth(); -} - -float Environment::get_fog_depth_end() const { - return fog_depth_end; -} - -void Environment::set_fog_depth_curve(float p_curve) { - fog_depth_curve = p_curve; - _update_fog_depth(); -} - -float Environment::get_fog_depth_curve() const { - return fog_depth_curve; -} - -void Environment::set_fog_transmit_enabled(bool p_enabled) { - fog_transmit_enabled = p_enabled; - _update_fog_depth(); -} - -bool Environment::is_fog_transmit_enabled() const { - return fog_transmit_enabled; -} - -void Environment::set_fog_transmit_curve(float p_curve) { - fog_transmit_curve = p_curve; - _update_fog_depth(); -} - -float Environment::get_fog_transmit_curve() const { - return fog_transmit_curve; -} - -void Environment::_update_fog_depth() { - RS::get_singleton()->environment_set_fog_depth( - environment, - fog_depth_enabled, - fog_depth_begin, - fog_depth_end, - fog_depth_curve, - fog_transmit_enabled, - fog_transmit_curve); -} - -void Environment::set_fog_height_enabled(bool p_enabled) { - fog_height_enabled = p_enabled; - _update_fog_height(); -} - -bool Environment::is_fog_height_enabled() const { - return fog_height_enabled; -} - -void Environment::set_fog_height_min(float p_distance) { - fog_height_min = p_distance; - _update_fog_height(); -} - -float Environment::get_fog_height_min() const { - return fog_height_min; -} - -void Environment::set_fog_height_max(float p_distance) { - fog_height_max = p_distance; - _update_fog_height(); -} - -float Environment::get_fog_height_max() const { - return fog_height_max; -} - -void Environment::set_fog_height_curve(float p_distance) { - fog_height_curve = p_distance; - _update_fog_height(); -} - -float Environment::get_fog_height_curve() const { - return fog_height_curve; -} - -void Environment::_update_fog_height() { - RS::get_singleton()->environment_set_fog_height( - environment, - fog_height_enabled, - fog_height_min, - fog_height_max, - fog_height_curve); + fog_light_color, + fog_light_energy, + fog_sun_scatter, + fog_density, + fog_height, + fog_height_density); } // Volumetric Fog @@ -1003,6 +912,7 @@ void Environment::_validate_property(PropertyInfo &property) const { static const char *hide_prefixes[] = { "fog_", + "volumetric_fog_", "auto_exposure_", "ss_reflections_", "ssao_", @@ -1290,52 +1200,31 @@ void Environment::_bind_methods() { ClassDB::bind_method(D_METHOD("set_fog_enabled", "enabled"), &Environment::set_fog_enabled); ClassDB::bind_method(D_METHOD("is_fog_enabled"), &Environment::is_fog_enabled); - ClassDB::bind_method(D_METHOD("set_fog_color", "color"), &Environment::set_fog_color); - ClassDB::bind_method(D_METHOD("get_fog_color"), &Environment::get_fog_color); - ClassDB::bind_method(D_METHOD("set_fog_sun_color", "color"), &Environment::set_fog_sun_color); - ClassDB::bind_method(D_METHOD("get_fog_sun_color"), &Environment::get_fog_sun_color); - ClassDB::bind_method(D_METHOD("set_fog_sun_amount", "amount"), &Environment::set_fog_sun_amount); - ClassDB::bind_method(D_METHOD("get_fog_sun_amount"), &Environment::get_fog_sun_amount); + ClassDB::bind_method(D_METHOD("set_fog_light_color", "light_color"), &Environment::set_fog_light_color); + ClassDB::bind_method(D_METHOD("get_fog_light_color"), &Environment::get_fog_light_color); + ClassDB::bind_method(D_METHOD("set_fog_light_energy", "light_energy"), &Environment::set_fog_light_energy); + ClassDB::bind_method(D_METHOD("get_fog_light_energy"), &Environment::get_fog_light_energy); + ClassDB::bind_method(D_METHOD("set_fog_sun_scatter", "sun_scatter"), &Environment::set_fog_sun_scatter); + ClassDB::bind_method(D_METHOD("get_fog_sun_scatter"), &Environment::get_fog_sun_scatter); - ClassDB::bind_method(D_METHOD("set_fog_depth_enabled", "enabled"), &Environment::set_fog_depth_enabled); - ClassDB::bind_method(D_METHOD("is_fog_depth_enabled"), &Environment::is_fog_depth_enabled); - ClassDB::bind_method(D_METHOD("set_fog_depth_begin", "distance"), &Environment::set_fog_depth_begin); - ClassDB::bind_method(D_METHOD("get_fog_depth_begin"), &Environment::get_fog_depth_begin); - ClassDB::bind_method(D_METHOD("set_fog_depth_end", "distance"), &Environment::set_fog_depth_end); - ClassDB::bind_method(D_METHOD("get_fog_depth_end"), &Environment::get_fog_depth_end); - ClassDB::bind_method(D_METHOD("set_fog_depth_curve", "curve"), &Environment::set_fog_depth_curve); - ClassDB::bind_method(D_METHOD("get_fog_depth_curve"), &Environment::get_fog_depth_curve); - ClassDB::bind_method(D_METHOD("set_fog_transmit_enabled", "enabled"), &Environment::set_fog_transmit_enabled); - ClassDB::bind_method(D_METHOD("is_fog_transmit_enabled"), &Environment::is_fog_transmit_enabled); - ClassDB::bind_method(D_METHOD("set_fog_transmit_curve", "curve"), &Environment::set_fog_transmit_curve); - ClassDB::bind_method(D_METHOD("get_fog_transmit_curve"), &Environment::get_fog_transmit_curve); + ClassDB::bind_method(D_METHOD("set_fog_density", "density"), &Environment::set_fog_density); + ClassDB::bind_method(D_METHOD("get_fog_density"), &Environment::get_fog_density); - ClassDB::bind_method(D_METHOD("set_fog_height_enabled", "enabled"), &Environment::set_fog_height_enabled); - ClassDB::bind_method(D_METHOD("is_fog_height_enabled"), &Environment::is_fog_height_enabled); - ClassDB::bind_method(D_METHOD("set_fog_height_min", "height"), &Environment::set_fog_height_min); - ClassDB::bind_method(D_METHOD("get_fog_height_min"), &Environment::get_fog_height_min); - ClassDB::bind_method(D_METHOD("set_fog_height_max", "height"), &Environment::set_fog_height_max); - ClassDB::bind_method(D_METHOD("get_fog_height_max"), &Environment::get_fog_height_max); - ClassDB::bind_method(D_METHOD("set_fog_height_curve", "curve"), &Environment::set_fog_height_curve); - ClassDB::bind_method(D_METHOD("get_fog_height_curve"), &Environment::get_fog_height_curve); + ClassDB::bind_method(D_METHOD("set_fog_height", "height"), &Environment::set_fog_height); + ClassDB::bind_method(D_METHOD("get_fog_height"), &Environment::get_fog_height); - ADD_GROUP("Fixed Fog", "fog_"); + ClassDB::bind_method(D_METHOD("set_fog_height_density", "height_density"), &Environment::set_fog_height_density); + ClassDB::bind_method(D_METHOD("get_fog_height_density"), &Environment::get_fog_height_density); + + ADD_GROUP("Fog", "fog_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "fog_enabled"), "set_fog_enabled", "is_fog_enabled"); - ADD_PROPERTY(PropertyInfo(Variant::COLOR, "fog_color"), "set_fog_color", "get_fog_color"); - ADD_PROPERTY(PropertyInfo(Variant::COLOR, "fog_sun_color"), "set_fog_sun_color", "get_fog_sun_color"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fog_sun_amount", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_fog_sun_amount", "get_fog_sun_amount"); + ADD_PROPERTY(PropertyInfo(Variant::COLOR, "fog_light_color", PROPERTY_HINT_COLOR_NO_ALPHA), "set_fog_light_color", "get_fog_light_color"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fog_light_energy", PROPERTY_HINT_RANGE, "0,16,0.01,or_greater"), "set_fog_light_energy", "get_fog_light_energy"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fog_sun_scatter", PROPERTY_HINT_RANGE, "0,1,0.01,or_greater"), "set_fog_sun_scatter", "get_fog_sun_scatter"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "fog_depth_enabled"), "set_fog_depth_enabled", "is_fog_depth_enabled"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fog_depth_begin", PROPERTY_HINT_RANGE, "0,4000,0.1"), "set_fog_depth_begin", "get_fog_depth_begin"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fog_depth_end", PROPERTY_HINT_RANGE, "0,4000,0.1,or_greater"), "set_fog_depth_end", "get_fog_depth_end"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fog_depth_curve", PROPERTY_HINT_EXP_EASING), "set_fog_depth_curve", "get_fog_depth_curve"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "fog_transmit_enabled"), "set_fog_transmit_enabled", "is_fog_transmit_enabled"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fog_transmit_curve", PROPERTY_HINT_EXP_EASING), "set_fog_transmit_curve", "get_fog_transmit_curve"); - - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "fog_height_enabled"), "set_fog_height_enabled", "is_fog_height_enabled"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fog_height_min", PROPERTY_HINT_RANGE, "-4000,4000,0.1,or_lesser,or_greater"), "set_fog_height_min", "get_fog_height_min"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fog_height_max", PROPERTY_HINT_RANGE, "-4000,4000,0.1,or_lesser,or_greater"), "set_fog_height_max", "get_fog_height_max"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fog_height_curve", PROPERTY_HINT_EXP_EASING), "set_fog_height_curve", "get_fog_height_curve"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fog_density", PROPERTY_HINT_RANGE, "0,16,0.0001"), "set_fog_density", "get_fog_density"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fog_height", PROPERTY_HINT_RANGE, "-1024,1024,0.01,or_lesser,or_greater"), "set_fog_height", "get_fog_height"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fog_height_density", PROPERTY_HINT_RANGE, "0,128,0.001,or_greater"), "set_fog_height_density", "get_fog_height_density"); ClassDB::bind_method(D_METHOD("set_volumetric_fog_enabled", "enabled"), &Environment::set_volumetric_fog_enabled); ClassDB::bind_method(D_METHOD("is_volumetric_fog_enabled"), &Environment::is_volumetric_fog_enabled); @@ -1444,8 +1333,6 @@ Environment::Environment() { _update_sdfgi(); _update_glow(); _update_fog(); - _update_fog_depth(); - _update_fog_height(); _update_adjustment(); _update_volumetric_fog(); _change_notify(); diff --git a/scene/resources/environment.h b/scene/resources/environment.h index 6edb54b187c..d4d84f31aa4 100644 --- a/scene/resources/environment.h +++ b/scene/resources/environment.h @@ -184,25 +184,15 @@ private: // Fog bool fog_enabled = false; - Color fog_color = Color(0.5, 0.6, 0.7); - Color fog_sun_color = Color(1.0, 0.9, 0.7); - float fog_sun_amount = 0.0; + Color fog_light_color = Color(0.5, 0.6, 0.7); + float fog_light_energy = 1.0; + float fog_sun_scatter = 0.0; + float fog_density = 0.001; + float fog_height = 0.0; + float fog_height_density = 0.0; //can be negative to invert effect + void _update_fog(); - bool fog_depth_enabled = true; - float fog_depth_begin = 10.0; - float fog_depth_end = 100.0; - float fog_depth_curve = 1.0; - bool fog_transmit_enabled = false; - float fog_transmit_curve = 1.0; - void _update_fog_depth(); - - bool fog_height_enabled = false; - float fog_height_min = 10.0; - float fog_height_max = 0.0; - float fog_height_curve = 1.0; - void _update_fog_height(); - // Volumetric Fog bool volumetric_fog_enabled = false; float volumetric_fog_density = 0.01; @@ -362,36 +352,22 @@ public: float get_glow_hdr_luminance_cap() const; // Fog + void set_fog_enabled(bool p_enabled); bool is_fog_enabled() const; - void set_fog_color(const Color &p_color); - Color get_fog_color() const; - void set_fog_sun_color(const Color &p_color); - Color get_fog_sun_color() const; - void set_fog_sun_amount(float p_amount); - float get_fog_sun_amount() const; + void set_fog_light_color(const Color &p_light_color); + Color get_fog_light_color() const; + void set_fog_light_energy(float p_amount); + float get_fog_light_energy() const; + void set_fog_sun_scatter(float p_amount); + float get_fog_sun_scatter() const; - void set_fog_depth_enabled(bool p_enabled); - bool is_fog_depth_enabled() const; - void set_fog_depth_begin(float p_distance); - float get_fog_depth_begin() const; - void set_fog_depth_end(float p_distance); - float get_fog_depth_end() const; - void set_fog_depth_curve(float p_curve); - float get_fog_depth_curve() const; - void set_fog_transmit_enabled(bool p_enabled); - bool is_fog_transmit_enabled() const; - void set_fog_transmit_curve(float p_curve); - float get_fog_transmit_curve() const; - - void set_fog_height_enabled(bool p_enabled); - bool is_fog_height_enabled() const; - void set_fog_height_min(float p_distance); - float get_fog_height_min() const; - void set_fog_height_max(float p_distance); - float get_fog_height_max() const; - void set_fog_height_curve(float p_distance); - float get_fog_height_curve() const; + void set_fog_density(float p_amount); + float get_fog_density() const; + void set_fog_height(float p_amount); + float get_fog_height() const; + void set_fog_height_density(float p_amount); + float get_fog_height_density() const; // Volumetric Fog void set_volumetric_fog_enabled(bool p_enable); diff --git a/servers/rendering/rasterizer.h b/servers/rendering/rasterizer.h index d7292972097..e1282fdf714 100644 --- a/servers/rendering/rasterizer.h +++ b/servers/rendering/rasterizer.h @@ -86,7 +86,6 @@ public: virtual void environment_set_glow(RID p_env, bool p_enable, int p_level_flags, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, RS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap) = 0; virtual void environment_glow_set_use_bicubic_upscale(bool p_enable) = 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_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_light, float p_light_energy, float p_lenght, float p_detail_spread, float p_gi_inject, RS::EnvVolumetricFogShadowFilter p_shadow_filter) = 0; @@ -111,9 +110,7 @@ public: virtual void environment_set_adjustment(RID p_env, bool p_enable, float p_brightness, float p_contrast, float p_saturation, RID p_ramp) = 0; - virtual void environment_set_fog(RID p_env, bool p_enable, const Color &p_color, const Color &p_sun_color, float p_sun_amount) = 0; - virtual void environment_set_fog_depth(RID p_env, bool p_enable, float p_depth_begin, float p_depth_end, float p_depth_curve, bool p_transmit, float p_transmit_curve) = 0; - virtual void environment_set_fog_height(RID p_env, bool p_enable, float p_min_height, float p_max_height, float p_height_curve) = 0; + virtual void environment_set_fog(RID p_env, bool p_enable, const Color &p_light_color, float p_light_energy, float p_sun_scatter, float p_density, float p_height, float p_height_density) = 0; virtual Ref environment_bake_panorama(RID p_env, bool p_bake_irradiance, const Size2i &p_size) = 0; diff --git a/servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.cpp b/servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.cpp index 78509f96422..f65c5d5de36 100644 --- a/servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.cpp +++ b/servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.cpp @@ -1146,6 +1146,7 @@ void RasterizerSceneHighEndRD::_setup_environment(RID p_environment, RID p_rende scene_state.ubo.gi_upscale_for_msaa = false; scene_state.ubo.volumetric_fog_enabled = false; + scene_state.ubo.fog_enabled = false; if (p_render_buffers.is_valid()) { RenderBufferDataHighEnd *render_buffers = (RenderBufferDataHighEnd *)render_buffers_get_data(p_render_buffers); @@ -1272,12 +1273,29 @@ void RasterizerSceneHighEndRD::_setup_environment(RID p_environment, RID p_rende scene_state.ubo.ssao_ao_affect = environment_get_ssao_ao_affect(p_environment); scene_state.ubo.ssao_light_affect = environment_get_ssao_light_affect(p_environment); - Color ao_color = environment_get_ao_color(p_environment); + Color ao_color = environment_get_ao_color(p_environment).to_linear(); scene_state.ubo.ao_color[0] = ao_color.r; scene_state.ubo.ao_color[1] = ao_color.g; scene_state.ubo.ao_color[2] = ao_color.b; scene_state.ubo.ao_color[3] = ao_color.a; + scene_state.ubo.fog_enabled = environment_is_fog_enabled(p_environment); + scene_state.ubo.fog_density = environment_get_fog_density(p_environment); + scene_state.ubo.fog_height = environment_get_fog_height(p_environment); + scene_state.ubo.fog_height_density = environment_get_fog_height_density(p_environment); + if (scene_state.ubo.fog_height_density >= 0.0001) { + scene_state.ubo.fog_height_density = 1.0 / scene_state.ubo.fog_height_density; + } + + Color fog_color = environment_get_fog_light_color(p_environment).to_linear(); + float fog_energy = environment_get_fog_light_energy(p_environment); + + scene_state.ubo.fog_light_color[0] = fog_color.r * fog_energy; + scene_state.ubo.fog_light_color[1] = fog_color.g * fog_energy; + scene_state.ubo.fog_light_color[2] = fog_color.b * fog_energy; + + scene_state.ubo.fog_sun_scatter = environment_get_fog_sun_scatter(p_environment); + } else { if (p_reflection_probe.is_valid() && storage->reflection_probe_is_interior(reflection_probe_instance_get_probe(p_reflection_probe))) { scene_state.ubo.use_ambient_light = false; diff --git a/servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.h b/servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.h index 1fb59453b56..1aad9039ff2 100644 --- a/servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.h +++ b/servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.h @@ -364,6 +364,16 @@ class RasterizerSceneHighEndRD : public RasterizerSceneRD { float volumetric_fog_inv_length; float volumetric_fog_detail_spread; uint32_t volumetric_fog_pad; + + // Fog + + uint32_t fog_enabled; + float fog_density; + float fog_height; + float fog_height_density; + + float fog_light_color[3]; + float fog_sun_scatter; }; UBO ubo; diff --git a/servers/rendering/rasterizer_rd/rasterizer_scene_rd.cpp b/servers/rendering/rasterizer_rd/rasterizer_scene_rd.cpp index 040124d5ab4..5e39455c295 100644 --- a/servers/rendering/rasterizer_rd/rasterizer_scene_rd.cpp +++ b/servers/rendering/rasterizer_rd/rasterizer_scene_rd.cpp @@ -2914,6 +2914,57 @@ void RasterizerSceneRD::environment_set_sdfgi(RID p_env, bool p_enable, RS::Envi env->sdfgi_y_scale = p_y_scale; } +void RasterizerSceneRD::environment_set_fog(RID p_env, bool p_enable, const Color &p_light_color, float p_light_energy, float p_sun_scatter, float p_density, float p_height, float p_height_density) { + Environment *env = environment_owner.getornull(p_env); + ERR_FAIL_COND(!env); + + env->fog_enabled = p_enable; + env->fog_light_color = p_light_color; + env->fog_light_energy = p_light_energy; + env->fog_sun_scatter = p_sun_scatter; + env->fog_density = p_density; + env->fog_height = p_height; + env->fog_height_density = p_height_density; +} + +bool RasterizerSceneRD::environment_is_fog_enabled(RID p_env) const { + const Environment *env = environment_owner.getornull(p_env); + ERR_FAIL_COND_V(!env, false); + + return env->fog_enabled; +} +Color RasterizerSceneRD::environment_get_fog_light_color(RID p_env) const { + const Environment *env = environment_owner.getornull(p_env); + ERR_FAIL_COND_V(!env, Color()); + return env->fog_light_color; +} +float RasterizerSceneRD::environment_get_fog_light_energy(RID p_env) const { + const Environment *env = environment_owner.getornull(p_env); + ERR_FAIL_COND_V(!env, 0); + return env->fog_light_energy; +} +float RasterizerSceneRD::environment_get_fog_sun_scatter(RID p_env) const { + const Environment *env = environment_owner.getornull(p_env); + ERR_FAIL_COND_V(!env, 0); + return env->fog_sun_scatter; +} +float RasterizerSceneRD::environment_get_fog_density(RID p_env) const { + const Environment *env = environment_owner.getornull(p_env); + ERR_FAIL_COND_V(!env, 0); + return env->fog_density; +} +float RasterizerSceneRD::environment_get_fog_height(RID p_env) const { + const Environment *env = environment_owner.getornull(p_env); + ERR_FAIL_COND_V(!env, 0); + + return env->fog_height; +} +float RasterizerSceneRD::environment_get_fog_height_density(RID p_env) const { + const Environment *env = environment_owner.getornull(p_env); + ERR_FAIL_COND_V(!env, 0); + return env->fog_height_density; +} + void RasterizerSceneRD::environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_light, float p_light_energy, float p_lenght, float p_detail_spread, float p_gi_inject, RenderingServer::EnvVolumetricFogShadowFilter p_shadow_filter) { Environment *env = environment_owner.getornull(p_env); ERR_FAIL_COND(!env); diff --git a/servers/rendering/rasterizer_rd/rasterizer_scene_rd.h b/servers/rendering/rasterizer_rd/rasterizer_scene_rd.h index 7c58a410d09..4c489605873 100644 --- a/servers/rendering/rasterizer_rd/rasterizer_scene_rd.h +++ b/servers/rendering/rasterizer_rd/rasterizer_scene_rd.h @@ -674,6 +674,15 @@ private: float auto_exp_scale = 0.5; uint64_t auto_exposure_version = 0; + // Fog + bool fog_enabled = false; + Color fog_light_color = Color(0.5, 0.6, 0.7); + float fog_light_energy = 1.0; + float fog_sun_scatter = 0.0; + float fog_density = 0.001; + float fog_height = 0.0; + float fog_height_density = 0.0; //can be negative to invert effect + /// Volumetric Fog /// bool volumetric_fog_enabled = false; @@ -1498,7 +1507,15 @@ public: void environment_set_glow(RID p_env, bool p_enable, int p_level_flags, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, RS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap); void environment_glow_set_use_bicubic_upscale(bool p_enable); - void environment_set_fog(RID p_env, bool p_enable, float p_begin, float p_end, RID p_gradient_texture) {} + void environment_set_fog(RID p_env, bool p_enable, const Color &p_light_color, float p_light_energy, float p_sun_scatter, float p_density, float p_height, float p_height_density); + bool environment_is_fog_enabled(RID p_env) const; + Color environment_get_fog_light_color(RID p_env) const; + float environment_get_fog_light_energy(RID p_env) const; + float environment_get_fog_sun_scatter(RID p_env) const; + float environment_get_fog_density(RID p_env) const; + float environment_get_fog_height(RID p_env) const; + float environment_get_fog_height_density(RID p_env) const; + void environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_light, float p_light_energy, float p_lenght, float p_detail_spread, float p_gi_inject, RS::EnvVolumetricFogShadowFilter p_shadow_filter); virtual void environment_set_volumetric_fog_volume_size(int p_size, int p_depth); @@ -1525,10 +1542,6 @@ public: void environment_set_tonemap(RID p_env, RS::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); void environment_set_adjustment(RID p_env, bool p_enable, float p_brightness, float p_contrast, float p_saturation, RID p_ramp) {} - void environment_set_fog(RID p_env, bool p_enable, const Color &p_color, const Color &p_sun_color, float p_sun_amount) {} - void environment_set_fog_depth(RID p_env, bool p_enable, float p_depth_begin, float p_depth_end, float p_depth_curve, bool p_transmit, float p_transmit_curve) {} - void environment_set_fog_height(RID p_env, bool p_enable, float p_min_height, float p_max_height, float p_height_curve) {} - virtual Ref environment_bake_panorama(RID p_env, bool p_bake_irradiance, const Size2i &p_size); virtual RID camera_effects_create(); diff --git a/servers/rendering/rasterizer_rd/shaders/scene_high_end.glsl b/servers/rendering/rasterizer_rd/shaders/scene_high_end.glsl index 837d7a3a5d7..5993e683179 100644 --- a/servers/rendering/rasterizer_rd/shaders/scene_high_end.glsl +++ b/servers/rendering/rasterizer_rd/shaders/scene_high_end.glsl @@ -1614,6 +1614,36 @@ vec4 volumetric_fog_process(vec2 screen_uv, float z) { return texture(sampler3D(volumetric_fog_texture, material_samplers[SAMPLER_LINEAR_CLAMP]), fog_pos); } +vec4 fog_process(vec3 vertex) { + vec3 fog_color = scene_data.fog_light_color; + + if (scene_data.fog_sun_scatter > 0.001) { + vec4 sun_scatter = vec4(0.0); + float sun_total = 0.0; + vec3 view = normalize(vertex); + + for (uint i = 0; i < scene_data.directional_light_count; i++) { + vec3 light_color = directional_lights.data[i].color * directional_lights.data[i].energy; + float light_amount = pow(max(dot(view, directional_lights.data[i].direction), 0.0), 8.0); + fog_color += light_color * light_amount * scene_data.fog_sun_scatter; + } + } + + float fog_amount = 1.0 - exp(vertex.z * scene_data.fog_density); + + if (abs(scene_data.fog_height_density) > 0.001) { + float y = (scene_data.camera_matrix * vec4(vertex, 1.0)).y; + + float y_dist = scene_data.fog_height - y; + + float vfog_amount = clamp(exp(y_dist * scene_data.fog_height_density), 0.0, 1.0); + + fog_amount = max(vfog_amount, fog_amount); + } + + return vec4(fog_color, fog_amount); +} + #endif void main() { @@ -2696,7 +2726,12 @@ FRAGMENT_SHADER_CODE vec4 fog = volumetric_fog_process(screen_uv, -vertex.z); diffuse_buffer.rgb = mix(diffuse_buffer.rgb, fog.rgb, fog.a); specular_buffer.rgb = mix(specular_buffer.rgb, vec3(0.0), fog.a); - ; + } + + if (scene_data.fog_enabled) { + vec4 fog = fog_process(vertex); + diffuse_buffer.rgb = mix(diffuse_buffer.rgb, fog.rgb, fog.a); + specular_buffer.rgb = mix(specular_buffer.rgb, vec3(0.0), fog.a); } #else //MODE_MULTIPLE_RENDER_TARGETS @@ -2713,6 +2748,11 @@ FRAGMENT_SHADER_CODE frag_color.rgb = mix(frag_color.rgb, fog.rgb, fog.a); } + if (scene_data.fog_enabled) { + vec4 fog = fog_process(vertex); + frag_color.rgb = mix(frag_color.rgb, fog.rgb, fog.a); + } + #endif //MODE_MULTIPLE_RENDER_TARGETS #endif //MODE_RENDER_DEPTH diff --git a/servers/rendering/rasterizer_rd/shaders/scene_high_end_inc.glsl b/servers/rendering/rasterizer_rd/shaders/scene_high_end_inc.glsl index 756cab73509..66bfefbe89f 100644 --- a/servers/rendering/rasterizer_rd/shaders/scene_high_end_inc.glsl +++ b/servers/rendering/rasterizer_rd/shaders/scene_high_end_inc.glsl @@ -100,40 +100,14 @@ layout(set = 0, binding = 3, std140) uniform SceneData { float volumetric_fog_inv_length; float volumetric_fog_detail_spread; uint volumetric_fog_pad; -#if 0 - vec4 ambient_light_color; - vec4 bg_color; - vec4 fog_color_enabled; - vec4 fog_sun_color_amount; - - float ambient_energy; - float bg_energy; -#endif - -#if 0 - vec2 shadow_atlas_pixel_size; - vec2 directional_shadow_pixel_size; - - float z_far; - - float subsurface_scatter_width; - float ambient_occlusion_affect_light; - float ambient_occlusion_affect_ao_channel; - float opaque_prepass_threshold; - - bool fog_depth_enabled; - float fog_depth_begin; - float fog_depth_end; + bool fog_enabled; float fog_density; - float fog_depth_curve; - bool fog_transmit_enabled; - float fog_transmit_curve; - bool fog_height_enabled; - float fog_height_min; - float fog_height_max; - float fog_height_curve; -#endif + float fog_height; + float fog_height_density; + + vec3 fog_light_color; + float fog_sun_scatter; } scene_data; diff --git a/servers/rendering/rendering_server_raster.h b/servers/rendering/rendering_server_raster.h index 75d3165c948..b4eac8cd760 100644 --- a/servers/rendering/rendering_server_raster.h +++ b/servers/rendering/rendering_server_raster.h @@ -562,9 +562,7 @@ public: BIND6(environment_set_adjustment, RID, bool, float, float, float, RID) - BIND5(environment_set_fog, RID, bool, const Color &, const Color &, float) - BIND7(environment_set_fog_depth, RID, bool, float, float, float, bool, float) - BIND5(environment_set_fog_height, RID, bool, float, float, float) + BIND8(environment_set_fog, RID, bool, const Color &, float, float, float, float, float) BIND9(environment_set_volumetric_fog, RID, bool, float, const Color &, float, float, float, float, EnvVolumetricFogShadowFilter) BIND2(environment_set_volumetric_fog_volume_size, int, int) diff --git a/servers/rendering/rendering_server_wrap_mt.h b/servers/rendering/rendering_server_wrap_mt.h index d7d0d968a2d..fb5c161c8a3 100644 --- a/servers/rendering/rendering_server_wrap_mt.h +++ b/servers/rendering/rendering_server_wrap_mt.h @@ -479,9 +479,8 @@ public: FUNC6(environment_set_adjustment, RID, bool, float, float, float, RID) - FUNC5(environment_set_fog, RID, bool, const Color &, const Color &, float) - FUNC7(environment_set_fog_depth, RID, bool, float, float, float, bool, float) - FUNC5(environment_set_fog_height, RID, bool, float, float, float) + FUNC8(environment_set_fog, RID, bool, const Color &, float, float, float, float, float) + FUNC9(environment_set_volumetric_fog, RID, bool, float, const Color &, float, float, float, float, EnvVolumetricFogShadowFilter) FUNC2(environment_set_volumetric_fog_volume_size, int, int) diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp index 714fe71d08b..3b034da3aa4 100644 --- a/servers/rendering_server.cpp +++ b/servers/rendering_server.cpp @@ -1747,11 +1747,7 @@ void RenderingServer::_bind_methods() { ClassDB::bind_method(D_METHOD("environment_set_adjustment", "env", "enable", "brightness", "contrast", "saturation", "ramp"), &RenderingServer::environment_set_adjustment); ClassDB::bind_method(D_METHOD("environment_set_ssr", "env", "enable", "max_steps", "fade_in", "fade_out", "depth_tolerance"), &RenderingServer::environment_set_ssr); ClassDB::bind_method(D_METHOD("environment_set_ssao", "env", "enable", "radius", "intensity", "bias", "light_affect", "ao_channel_affect", "blur", "bilateral_sharpness"), &RenderingServer::environment_set_ssao); - ClassDB::bind_method(D_METHOD("environment_set_fog", "env", "enable", "color", "sun_color", "sun_amount"), &RenderingServer::environment_set_fog); - - ClassDB::bind_method(D_METHOD("environment_set_fog_depth", "env", "enable", "depth_begin", "depth_end", "depth_curve", "transmit", "transmit_curve"), &RenderingServer::environment_set_fog_depth); - - ClassDB::bind_method(D_METHOD("environment_set_fog_height", "env", "enable", "min_height", "max_height", "height_curve"), &RenderingServer::environment_set_fog_height); + ClassDB::bind_method(D_METHOD("environment_set_fog", "env", "enable", "light_color", "light_energy", "sun_scatter", "density", "height", "height_density"), &RenderingServer::environment_set_fog); ClassDB::bind_method(D_METHOD("scenario_create"), &RenderingServer::scenario_create); ClassDB::bind_method(D_METHOD("scenario_set_debug", "scenario", "debug_mode"), &RenderingServer::scenario_set_debug); diff --git a/servers/rendering_server.h b/servers/rendering_server.h index 57af53f0c02..a13fd4954bb 100644 --- a/servers/rendering_server.h +++ b/servers/rendering_server.h @@ -862,9 +862,7 @@ public: virtual void environment_set_sdfgi_frames_to_converge(EnvironmentSDFGIFramesToConverge p_frames) = 0; - virtual void environment_set_fog(RID p_env, bool p_enable, const Color &p_color, const Color &p_sun_color, float p_sun_amount) = 0; - virtual void environment_set_fog_depth(RID p_env, bool p_enable, float p_depth_begin, float p_depth_end, float p_depth_curve, bool p_transmit, float p_transmit_curve) = 0; - virtual void environment_set_fog_height(RID p_env, bool p_enable, float p_min_height, float p_max_height, float p_height_curve) = 0; + virtual void environment_set_fog(RID p_env, bool p_enable, const Color &p_light_color, float p_light_energy, float p_sun_scatter, float p_density, float p_height, float p_height_density) = 0; enum EnvVolumetricFogShadowFilter { ENV_VOLUMETRIC_FOG_SHADOW_FILTER_DISABLED,