Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Add optional depth fog to Environment #66030

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions doc/classes/Environment.xml
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,21 @@
<member name="fog_density" type="float" setter="set_fog_density" getter="get_fog_density" default="0.01">
The [i]exponential[/i] fog density to use. Higher values result in a more dense fog. Fog rendering is exponential as in real life.
</member>
<member name="fog_depth_begin" type="float" setter="set_fog_depth_begin" getter="get_fog_depth_begin" default="10.0">
The fog's depth starting distance from the camera.
</member>
<member name="fog_depth_curve" type="float" setter="set_fog_depth_curve" getter="get_fog_depth_curve" default="1.0">
The fog depth's intensity curve. A number of presets are available in the Inspector by right-clicking the curve.
</member>
<member name="fog_depth_density" type="float" setter="set_fog_depth_density" getter="get_fog_depth_density" default="1.0">
The maximum intensity of the depth fog effect.
</member>
<member name="fog_depth_enabled" type="bool" setter="set_fog_depth_enabled" getter="is_fog_depth_enabled" default="false">
If [code]true[/code], the depth fog effect is enabled. When enabled, fog will appear in the distance (relative to the camera).
</member>
<member name="fog_depth_end" type="float" setter="set_fog_depth_end" getter="get_fog_depth_end" default="100.0">
The fog's depth end distance from the camera. If this value is set to 0, it will be equal to the current camera's Camera.far value.
</member>
<member name="fog_enabled" type="bool" setter="set_fog_enabled" getter="is_fog_enabled" default="false">
If [code]true[/code], fog effects are enabled.
</member>
Expand Down
9 changes: 9 additions & 0 deletions drivers/gles3/rasterizer_scene_gles3.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1444,6 +1444,11 @@ void RasterizerSceneGLES3::_setup_environment(const RenderDataGLES3 *p_render_da
scene_state.ubo.fog_enabled = environment_get_fog_enabled(p_render_data->environment);
scene_state.ubo.fog_density = environment_get_fog_density(p_render_data->environment);
scene_state.ubo.fog_height = environment_get_fog_height(p_render_data->environment);
scene_state.ubo.fog_depth_enabled = environment_get_fog_depth_enabled(p_render_data->environment);
scene_state.ubo.fog_depth_curve = environment_get_fog_depth_curve(p_render_data->environment);
scene_state.ubo.fog_depth_density = environment_get_fog_depth_density(p_render_data->environment);
scene_state.ubo.fog_depth_begin = environment_get_fog_depth_begin(p_render_data->environment);
scene_state.ubo.fog_depth_end = environment_get_fog_depth_end(p_render_data->environment);
scene_state.ubo.fog_height_density = environment_get_fog_height_density(p_render_data->environment);
scene_state.ubo.fog_aerial_perspective = environment_get_fog_aerial_perspective(p_render_data->environment);

Expand Down Expand Up @@ -1974,6 +1979,10 @@ void RasterizerSceneGLES3::render_scene(const Ref<RenderSceneBuffers> &p_render_
if (render_data.environment.is_null() || (render_data.environment.is_valid() && !environment_get_fog_enabled(render_data.environment))) {
spec_constant_base_flags |= 1 << SPEC_CONSTANT_DISABLE_FOG;
}

if (render_data.environment.is_null() || (render_data.environment.is_valid() && environment_get_fog_enabled(render_data.environment) && !environment_get_fog_depth_enabled(render_data.environment))) {
spec_constant_base_flags |= 1 << SPEC_CONSTANT_DISABLE_FOG_DEPTH;
}
}
// Render Opaque Objects.
RenderListParameters render_list_params(render_list[RENDER_LIST_OPAQUE].elements.ptr(), render_list[RENDER_LIST_OPAQUE].elements.size(), reverse_cull, spec_constant_base_flags, use_wireframe);
Expand Down
11 changes: 11 additions & 0 deletions drivers/gles3/rasterizer_scene_gles3.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ enum {
SPEC_CONSTANT_DISABLE_OMNI_LIGHTS = 2,
SPEC_CONSTANT_DISABLE_SPOT_LIGHTS = 3,
SPEC_CONSTANT_DISABLE_FOG = 4,
SPEC_CONSTANT_DISABLE_FOG_DEPTH = 5,
};

struct RenderDataGLES3 {
Expand Down Expand Up @@ -366,8 +367,18 @@ class RasterizerSceneGLES3 : public RendererSceneRender {
float fog_height;
float fog_height_density;

uint32_t fog_depth_enabled;
float fog_depth_curve;
float fog_depth_density;
float fog_depth_begin;

float fog_light_color[3];
float fog_depth_end;

float fog_sun_scatter;
float pad1;
float pad3;
float pad4;
};
static_assert(sizeof(UBO) % 16 == 0, "Scene UBO size must be a multiple of 16 bytes");

Expand Down
31 changes: 31 additions & 0 deletions drivers/gles3/shaders/scene.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ DISABLE_LIGHT_DIRECTIONAL = false
DISABLE_LIGHT_OMNI = false
DISABLE_LIGHT_SPOT = false
DISABLE_FOG = false
DISABLE_FOG_DEPTH = false
USE_RADIANCE_MAP = true


Expand Down Expand Up @@ -148,8 +149,18 @@ layout(std140) uniform SceneData { // ubo:2
float fog_height;
float fog_height_density;

bool fog_depth_enabled;
float fog_depth_curve;
float fog_depth_density;
float fog_depth_begin;

vec3 fog_light_color;
float fog_depth_end;

float fog_sun_scatter;
float pad1;
float pad3;
float pad4;
}
scene_data;

Expand Down Expand Up @@ -458,8 +469,18 @@ layout(std140) uniform SceneData { // ubo:2
float fog_height;
float fog_height_density;

bool fog_depth_enabled;
float fog_depth_curve;
float fog_depth_density;
float fog_depth_begin;

vec3 fog_light_color;
float fog_depth_end;

float fog_sun_scatter;
float pad1;
float pad3;
float pad4;
}
scene_data;

Expand Down Expand Up @@ -866,6 +887,16 @@ vec4 fog_process(vec3 vertex) {

float fog_amount = 1.0 - exp(min(0.0, -length(vertex) * scene_data.fog_density));

#ifndef DISABLE_FOG_DEPTH
if (scene_data.fog_depth_enabled) {
float fog_far = scene_data.fog_depth_end > 0.0 ? scene_data.fog_depth_end : scene_data.z_far;
float fog_z = smoothstep(scene_data.fog_depth_begin, fog_far, length(vertex));

float fog_quad_amount = pow(fog_z, scene_data.fog_depth_curve) * scene_data.fog_depth_density;
fog_amount = max(fog_quad_amount, fog_amount);
}
#endif

if (abs(scene_data.fog_height_density) >= 0.0001) {
float y = (scene_data.inv_view_matrix * vec4(vertex, 1.0)).y;

Expand Down
74 changes: 74 additions & 0 deletions scene/resources/environment.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -841,6 +841,63 @@ void Environment::_update_fog() {
fog_sky_affect);
}

// Depth Fog

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_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_depth_density(float p_density) {
fog_depth_density = p_density;
_update_fog_depth();
}

float Environment::get_fog_depth_density() const {
return fog_depth_density;
}

void Environment::set_fog_depth_begin(float p_begin) {
fog_depth_begin = p_begin;
_update_fog_depth();
}

float Environment::get_fog_depth_begin() const {
return fog_depth_begin;
}

void Environment::set_fog_depth_end(float p_end) {
fog_depth_end = p_end;
_update_fog_depth();
}

float Environment::get_fog_depth_end() const {
return fog_depth_end;
}

void Environment::_update_fog_depth() {
RS::get_singleton()->environment_set_fog_depth(
environment,
fog_depth_enabled,
fog_depth_curve,
fog_depth_density,
fog_depth_begin,
fog_depth_end);
}

// Volumetric Fog

void Environment::_update_volumetric_fog() {
Expand Down Expand Up @@ -1411,6 +1468,17 @@ void Environment::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_fog_sky_affect", "sky_affect"), &Environment::set_fog_sky_affect);
ClassDB::bind_method(D_METHOD("get_fog_sky_affect"), &Environment::get_fog_sky_affect);

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_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_depth_density", "density"), &Environment::set_fog_depth_density);
ClassDB::bind_method(D_METHOD("get_fog_depth_density"), &Environment::get_fog_depth_density);
ClassDB::bind_method(D_METHOD("set_fog_depth_begin", "begin"), &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", "end"), &Environment::set_fog_depth_end);
ClassDB::bind_method(D_METHOD("get_fog_depth_end"), &Environment::get_fog_depth_end);

ADD_GROUP("Fog", "fog_");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "fog_enabled"), "set_fog_enabled", "is_fog_enabled");
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "fog_light_color", PROPERTY_HINT_COLOR_NO_ALPHA), "set_fog_light_color", "get_fog_light_color");
Expand All @@ -1423,6 +1491,12 @@ void Environment::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fog_height", PROPERTY_HINT_RANGE, "-1024,1024,0.01,or_less,or_greater,suffix:m"), "set_fog_height", "get_fog_height");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fog_height_density", PROPERTY_HINT_RANGE, "-16,16,0.0001,or_less,or_greater"), "set_fog_height_density", "get_fog_height_density");

ADD_PROPERTY(PropertyInfo(Variant::BOOL, "fog_depth_enabled"), "set_fog_depth_enabled", "is_fog_depth_enabled");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fog_depth_curve", PROPERTY_HINT_EXP_EASING), "set_fog_depth_curve", "get_fog_depth_curve");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fog_depth_density", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_fog_depth_density", "get_fog_depth_density");
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");

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);
ClassDB::bind_method(D_METHOD("set_volumetric_fog_emission", "color"), &Environment::set_volumetric_fog_emission);
Expand Down
21 changes: 21 additions & 0 deletions scene/resources/environment.h
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,15 @@ class Environment : public Resource {

void _update_fog();

// Depth Fog
bool fog_depth_enabled = false;
float fog_depth_curve = 1.0;
float fog_depth_density = 1.0;
float fog_depth_begin = 10.0;
float fog_depth_end = 100.0;

void _update_fog_depth();

// Volumetric Fog
bool volumetric_fog_enabled = false;
float volumetric_fog_density = 0.05;
Expand Down Expand Up @@ -379,6 +388,18 @@ class Environment : public Resource {
void set_fog_sky_affect(float p_sky_affect);
float get_fog_sky_affect() const;

// Depth Fog
void set_fog_depth_enabled(bool p_enabled);
bool is_fog_depth_enabled() const;
void set_fog_depth_curve(float p_curve);
float get_fog_depth_curve() const;
void set_fog_depth_density(float p_density);
float get_fog_depth_density() const;
void set_fog_depth_begin(float p_begin);
float get_fog_depth_begin() const;
void set_fog_depth_end(float p_end);
float get_fog_depth_end() const;

// Volumetric Fog
void set_volumetric_fog_enabled(bool p_enable);
bool is_volumetric_fog_enabled() const;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ class RenderForwardClustered : public RendererSceneRenderRD {
SPEC_CONSTANT_DIRECTIONAL_PENUMBRA_SHADOW_SAMPLES = 9,
SPEC_CONSTANT_DECAL_FILTER = 10,
SPEC_CONSTANT_PROJECTOR_FILTER = 11,
SPEC_CONSTANT_DISABLE_FOG_DEPTH = 12,
};

enum {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -732,6 +732,10 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
if (!is_environment(p_render_data->environment) || environment_get_fog_enabled(p_render_data->environment)) {
spec_constant_base_flags |= 1 << SPEC_CONSTANT_DISABLE_FOG;
}

if (!is_environment(p_render_data->environment) || !environment_get_fog_enabled(p_render_data->environment) || !environment_get_fog_depth_enabled(p_render_data->environment)) {
spec_constant_base_flags |= 1 << SPEC_CONSTANT_DISABLE_FOG_DEPTH;
}
}
{
if (rb_data.is_valid()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ class RenderForwardMobile : public RendererSceneRenderRD {

SPEC_CONSTANT_DISABLE_DECALS = 13,
SPEC_CONSTANT_DISABLE_FOG = 14,
SPEC_CONSTANT_DISABLE_FOG_DEPTH = 16,

};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -432,6 +432,7 @@ layout(constant_id = 9) const uint sc_directional_penumbra_shadow_samples = 4;

layout(constant_id = 10) const bool sc_decal_use_mipmaps = true;
layout(constant_id = 11) const bool sc_projector_use_mipmaps = true;
layout(constant_id = 12) const bool sc_disable_fog_depth = false;

// not used in clustered renderer but we share some code with the mobile renderer that requires this.
const float sc_luminance_multiplier = 1.0;
Expand Down Expand Up @@ -614,6 +615,14 @@ vec4 fog_process(vec3 vertex) {

float fog_amount = 1.0 - exp(min(0.0, -length(vertex) * scene_data_block.data.fog_density));

if (!sc_disable_fog_depth && scene_data_block.data.fog_depth_enabled) {
float fog_far = scene_data_block.data.fog_depth_end > 0.0 ? scene_data_block.data.fog_depth_end : scene_data_block.data.z_far;
float fog_z = smoothstep(scene_data_block.data.fog_depth_begin, fog_far, length(vertex));

float fog_quad_amount = pow(fog_z, scene_data_block.data.fog_depth_curve) * scene_data_block.data.fog_depth_density;
fog_amount = max(fog_quad_amount, fog_amount);
}

if (abs(scene_data_block.data.fog_height_density) >= 0.0001) {
float y = (scene_data_block.data.inv_view_matrix * vec4(vertex, 1.0)).y;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -415,6 +415,7 @@ layout(constant_id = 12) const bool sc_disable_directional_lights = false;
layout(constant_id = 7) const bool sc_decal_use_mipmaps = true;
layout(constant_id = 13) const bool sc_disable_decals = false;
layout(constant_id = 14) const bool sc_disable_fog = false;
layout(constant_id = 16) const bool sc_disable_fog_depth = false;

#endif //!MODE_RENDER_DEPTH

Expand Down Expand Up @@ -571,6 +572,14 @@ vec4 fog_process(vec3 vertex) {

float fog_amount = 1.0 - exp(min(0.0, -length(vertex) * scene_data_block.data.fog_density));

if (!sc_disable_fog_depth && scene_data_block.data.fog_depth_enabled) {
float fog_far = scene_data_block.data.fog_depth_end > 0.0 ? scene_data_block.data.fog_depth_end : scene_data_block.data.z_far;
float fog_z = smoothstep(scene_data_block.data.fog_depth_begin, fog_far, length(vertex));

float fog_quad_amount = pow(fog_z, scene_data_block.data.fog_depth_curve) * scene_data_block.data.fog_depth_density;
fog_amount = max(fog_quad_amount, fog_amount);
}

if (abs(scene_data_block.data.fog_height_density) >= 0.0001) {
float y = (scene_data_block.data.inv_view_matrix * vec4(vertex, 1.0)).y;

Expand Down
15 changes: 11 additions & 4 deletions servers/rendering/renderer_rd/shaders/scene_data_inc.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -50,20 +50,27 @@ struct SceneData {
highp float fog_height;
highp float fog_height_density;

bool fog_depth_enabled;
highp float fog_depth_curve;
highp float fog_depth_density;
highp float fog_depth_begin;

mediump vec3 fog_light_color;
mediump float fog_sun_scatter;
highp float fog_depth_end;

mediump float fog_sun_scatter;
mediump float fog_aerial_perspective;
highp float time;
mediump float reflection_multiplier; // one normally, zero when rendering reflections
bool material_uv2_mode;

vec2 taa_jitter;
bool material_uv2_mode;
float emissive_exposure_normalization;
float IBL_exposure_normalization;

float IBL_exposure_normalization;
bool pancake_shadows;
uint pad1;
uint pad2;
uint pad3;

vec4 pad3;
};
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,12 @@ void RenderSceneDataRD::update_ubo(RID p_uniform_buffer, RS::ViewportDebugDraw p
ubo.fog_height_density = render_scene_render->environment_get_fog_height_density(p_env);
ubo.fog_aerial_perspective = render_scene_render->environment_get_fog_aerial_perspective(p_env);

ubo.fog_depth_enabled = render_scene_render->environment_get_fog_depth_enabled(p_env);
ubo.fog_depth_curve = render_scene_render->environment_get_fog_depth_curve(p_env);
ubo.fog_depth_density = render_scene_render->environment_get_fog_depth_density(p_env);
ubo.fog_depth_begin = render_scene_render->environment_get_fog_depth_begin(p_env);
ubo.fog_depth_end = render_scene_render->environment_get_fog_depth_end(p_env);

Color fog_color = render_scene_render->environment_get_fog_light_color(p_env).srgb_to_linear();
float fog_energy = render_scene_render->environment_get_fog_light_energy(p_env);

Expand Down
Loading