summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gles3/rasterizer_scene_gles3.cpp61
-rw-r--r--drivers/gles3/rasterizer_scene_gles3.h52
-rw-r--r--drivers/gles3/shader_compiler_gles3.cpp1
-rw-r--r--drivers/gles3/shaders/scene.glsl70
4 files changed, 184 insertions, 0 deletions
diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp
index de79c034cb..af03819a16 100644
--- a/drivers/gles3/rasterizer_scene_gles3.cpp
+++ b/drivers/gles3/rasterizer_scene_gles3.cpp
@@ -944,6 +944,40 @@ void RasterizerSceneGLES3::environment_set_adjustment(RID p_env, bool p_enable,
env->color_correction = p_ramp;
}
+void RasterizerSceneGLES3::environment_set_fog(RID p_env, bool p_enable, const Color &p_color, const Color &p_sun_color, float p_sun_amount) {
+
+ Environment *env = environment_owner.getornull(p_env);
+ ERR_FAIL_COND(!env);
+
+ env->fog_enabled = p_enable;
+ env->fog_color = p_color;
+ env->fog_sun_color = p_sun_color;
+ env->fog_sun_amount = p_sun_amount;
+}
+
+void RasterizerSceneGLES3::environment_set_fog_depth(RID p_env, bool p_enable, float p_depth_begin, float p_depth_curve, bool p_transmit, float p_transmit_curve) {
+
+ Environment *env = environment_owner.getornull(p_env);
+ ERR_FAIL_COND(!env);
+
+ env->fog_depth_enabled = p_enable;
+ env->fog_depth_begin = p_depth_begin;
+ env->fog_depth_curve = p_depth_curve;
+ env->fog_transmit_enabled = p_transmit;
+ env->fog_transmit_curve = p_transmit_curve;
+}
+
+void RasterizerSceneGLES3::environment_set_fog_height(RID p_env, bool p_enable, float p_min_height, float p_max_height, float p_height_curve) {
+
+ Environment *env = environment_owner.getornull(p_env);
+ ERR_FAIL_COND(!env);
+
+ env->fog_height_enabled = p_enable;
+ env->fog_height_min = p_min_height;
+ env->fog_height_max = p_max_height;
+ env->fog_height_curve = p_height_curve;
+}
+
RID RasterizerSceneGLES3::light_instance_create(RID p_light) {
LightInstance *light_instance = memnew(LightInstance);
@@ -2224,6 +2258,7 @@ void RasterizerSceneGLES3::_setup_environment(Environment *env, const CameraMatr
state.ubo_data.time[i] = storage->frame.time[i];
}
+ state.ubo_data.z_far = p_cam_projection.get_z_far();
//bg and ambient
if (env) {
state.ubo_data.bg_energy = env->bg_energy;
@@ -2255,6 +2290,30 @@ void RasterizerSceneGLES3::_setup_environment(Environment *env, const CameraMatr
state.env_radiance_data.ambient_contribution = env->ambient_sky_contribution;
state.ubo_data.ambient_occlusion_affect_light = env->ssao_light_affect;
+
+ //fog
+
+ Color linear_fog = env->fog_color.to_linear();
+ state.ubo_data.fog_color_enabled[0] = linear_fog.r;
+ state.ubo_data.fog_color_enabled[1] = linear_fog.g;
+ state.ubo_data.fog_color_enabled[2] = linear_fog.b;
+ state.ubo_data.fog_color_enabled[3] = env->fog_enabled ? 1.0 : 0.0;
+
+ Color linear_sun = env->fog_sun_color.to_linear();
+ state.ubo_data.fog_sun_color_amount[0] = linear_sun.r;
+ state.ubo_data.fog_sun_color_amount[1] = linear_sun.g;
+ state.ubo_data.fog_sun_color_amount[2] = linear_sun.b;
+ state.ubo_data.fog_sun_color_amount[3] = env->fog_sun_amount;
+ state.ubo_data.fog_depth_enabled = env->fog_depth_enabled;
+ state.ubo_data.fog_depth_begin = env->fog_depth_begin;
+ state.ubo_data.fog_depth_curve = env->fog_depth_curve;
+ state.ubo_data.fog_transmit_enabled = env->fog_transmit_enabled;
+ state.ubo_data.fog_transmit_curve = env->fog_transmit_curve;
+ state.ubo_data.fog_height_enabled = env->fog_height_enabled;
+ state.ubo_data.fog_height_min = env->fog_height_min;
+ state.ubo_data.fog_height_max = env->fog_height_max;
+ state.ubo_data.fog_height_curve = env->fog_height_curve;
+
} else {
state.ubo_data.bg_energy = 1.0;
state.ubo_data.ambient_energy = 1.0;
@@ -2272,6 +2331,8 @@ void RasterizerSceneGLES3::_setup_environment(Environment *env, const CameraMatr
state.env_radiance_data.ambient_contribution = 0;
state.ubo_data.ambient_occlusion_affect_light = 0;
+
+ state.ubo_data.fog_color_enabled[3] = 0.0;
}
{
diff --git a/drivers/gles3/rasterizer_scene_gles3.h b/drivers/gles3/rasterizer_scene_gles3.h
index 03c6f080ac..55d314a800 100644
--- a/drivers/gles3/rasterizer_scene_gles3.h
+++ b/drivers/gles3/rasterizer_scene_gles3.h
@@ -111,6 +111,9 @@ public:
float time[4];
float ambient_light_color[4];
float bg_color[4];
+ float fog_color_enabled[4];
+ float fog_sun_color_amount[4];
+
float ambient_energy;
float bg_energy;
float shadow_z_offset;
@@ -120,10 +123,22 @@ public:
float screen_pixel_size[2];
float shadow_atlas_pixel_size[2];
float shadow_directional_pixel_size[2];
+
+ float z_far;
float reflection_multiplier;
float subsurface_scatter_width;
float ambient_occlusion_affect_light;
+ bool fog_depth_enabled;
+ float fog_depth_begin;
+ 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;
+
} ubo_data;
GLuint scene_ubo;
@@ -396,6 +411,21 @@ public:
float adjustments_saturation;
RID color_correction;
+ bool fog_enabled;
+ Color fog_color;
+ Color fog_sun_color;
+ float fog_sun_amount;
+
+ bool fog_depth_enabled;
+ float fog_depth_begin;
+ 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;
+
Environment() {
bg_mode = VS::ENV_BG_CLEAR_COLOR;
sky_scale = 1.0;
@@ -457,6 +487,24 @@ public:
adjustments_brightness = 1.0;
adjustments_contrast = 1.0;
adjustments_saturation = 1.0;
+
+ fog_enabled = false;
+ fog_color = Color(0.5, 0.5, 0.5);
+ fog_sun_color = Color(0.8, 0.8, 0.0);
+ fog_sun_amount = 0;
+
+ fog_depth_enabled = true;
+
+ fog_depth_begin = 10;
+ fog_depth_curve = 1;
+
+ fog_transmit_enabled = true;
+ fog_transmit_curve = 1;
+
+ fog_height_enabled = false;
+ fog_height_min = 0;
+ fog_height_max = 100;
+ fog_height_curve = 1;
}
};
@@ -484,6 +532,10 @@ public:
virtual void environment_set_adjustment(RID p_env, bool p_enable, float p_brightness, float p_contrast, float p_saturation, RID p_ramp);
+ virtual void environment_set_fog(RID p_env, bool p_enable, const Color &p_color, const Color &p_sun_color, float p_sun_amount);
+ virtual void environment_set_fog_depth(RID p_env, bool p_enable, float p_depth_begin, float p_depth_curve, bool p_transmit, float p_transmit_curve);
+ virtual void environment_set_fog_height(RID p_env, bool p_enable, float p_min_height, float p_max_height, float p_height_curve);
+
/* LIGHT INSTANCE */
struct LightDataUBO {
diff --git a/drivers/gles3/shader_compiler_gles3.cpp b/drivers/gles3/shader_compiler_gles3.cpp
index 4f741c6b7a..b1f7b4c9bd 100644
--- a/drivers/gles3/shader_compiler_gles3.cpp
+++ b/drivers/gles3/shader_compiler_gles3.cpp
@@ -747,6 +747,7 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() {
actions[VS::SHADER_SPATIAL].renames["INSTANCE_CUSTOM"] = "instance_custom";
actions[VS::SHADER_SPATIAL].renames["SCREEN_UV"] = "screen_uv";
actions[VS::SHADER_SPATIAL].renames["SCREEN_TEXTURE"] = "screen_texture";
+ actions[VS::SHADER_SPATIAL].renames["DEPTH_TEXTURE"] = "depth_buffer";
actions[VS::SHADER_SPATIAL].renames["SIDE"] = "side";
actions[VS::SHADER_SPATIAL].usage_defines["TANGENT"] = "#define ENABLE_TANGENT_INTERP\n";
diff --git a/drivers/gles3/shaders/scene.glsl b/drivers/gles3/shaders/scene.glsl
index f498eae9f5..8965f475d7 100644
--- a/drivers/gles3/shaders/scene.glsl
+++ b/drivers/gles3/shaders/scene.glsl
@@ -67,6 +67,10 @@ layout(std140) uniform SceneData { //ubo:0
highp vec4 ambient_light_color;
highp vec4 bg_color;
+
+ vec4 fog_color_enabled;
+ vec4 fog_sun_color_amount;
+
float ambient_energy;
float bg_energy;
@@ -79,10 +83,21 @@ layout(std140) uniform SceneData { //ubo:0
vec2 shadow_atlas_pixel_size;
vec2 directional_shadow_pixel_size;
+ float z_far;
float reflection_multiplier;
float subsurface_scatter_width;
float ambient_occlusion_affect_light;
+ bool fog_depth_enabled;
+ float fog_depth_begin;
+ 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;
+
};
uniform highp mat4 world_transform;
@@ -425,6 +440,8 @@ layout(std140) uniform SceneData {
highp vec4 ambient_light_color;
highp vec4 bg_color;
+ vec4 fog_color_enabled;
+ vec4 fog_sun_color_amount;
float ambient_energy;
float bg_energy;
@@ -438,10 +455,20 @@ layout(std140) uniform SceneData {
vec2 shadow_atlas_pixel_size;
vec2 directional_shadow_pixel_size;
+ float z_far;
float reflection_multiplier;
float subsurface_scatter_width;
float ambient_occlusion_affect_light;
+ bool fog_depth_enabled;
+ float fog_depth_begin;
+ 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;
};
//directional light data
@@ -1615,6 +1642,49 @@ FRAGMENT_SHADER_CODE
specular_light *= min(1.0,50.0 * f0.g) * brdf.y + brdf.x * f0;
}
+ if (fog_color_enabled.a > 0.5) {
+
+ float fog_amount=0;
+
+
+
+#ifdef USE_LIGHT_DIRECTIONAL
+
+ vec3 fog_color = mix( fog_color_enabled.rgb, fog_sun_color_amount.rgb,fog_sun_color_amount.a * pow(max( dot(normalize(vertex),-light_direction_attenuation.xyz), 0.0),8.0) );
+#else
+
+ vec3 fog_color = fog_color_enabled.rgb;
+#endif
+
+ //apply fog
+
+ if (fog_depth_enabled) {
+
+ float fog_z = smoothstep(fog_depth_begin,z_far,-vertex.z);
+
+ fog_amount = pow(fog_z,fog_depth_curve);
+ if (fog_transmit_enabled) {
+ vec3 total_light = emission + ambient_light + specular_light + diffuse_light;
+ float transmit = pow(fog_z,fog_transmit_curve);
+ fog_color = mix(max(total_light,fog_color),fog_color,transmit);
+ }
+ }
+
+ if (fog_height_enabled) {
+ float y = (camera_matrix * vec4(vertex,1.0)).y;
+ fog_amount = max(fog_amount,pow(1.0-smoothstep(fog_height_min,fog_height_max,y),fog_height_curve));
+ }
+
+ float rev_amount = 1.0 - fog_amount;
+
+
+ emission = emission * rev_amount + fog_color * fog_amount;
+ ambient_light*=rev_amount;
+ specular_light*rev_amount;
+ diffuse_light*=rev_amount;
+
+ }
+
#ifdef USE_MULTIPLE_RENDER_TARGETS
#if defined(ENABLE_AO)