[Bf-blender-cvs] [dfcdec914ce] blender2.8: Eevee: Shadows: Add Contact Shadows

Clément Foucault noreply at git.blender.org
Fri Oct 6 23:44:31 CEST 2017


Commit: dfcdec914ce918adf6c47d3c1e278b5a5c22fb4d
Author: Clément Foucault
Date:   Fri Oct 6 23:43:36 2017 +0200
Branches: blender2.8
https://developer.blender.org/rBdfcdec914ce918adf6c47d3c1e278b5a5c22fb4d

Eevee: Shadows: Add Contact Shadows

This add the possibility to add screen space raytraced shadows to fix light leaking cause by shadows maps.

Theses inherit of the same artifacts as other screenspace methods.

===================================================================

M	release/scripts/startup/bl_ui/properties_data_lamp.py
M	source/blender/blenkernel/intern/lamp.c
M	source/blender/blenloader/intern/versioning_280.c
M	source/blender/draw/engines/eevee/eevee_lights.c
M	source/blender/draw/engines/eevee/eevee_private.h
M	source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl
M	source/blender/draw/engines/eevee/shaders/lamps_lib.glsl
M	source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl
M	source/blender/makesdna/DNA_lamp_types.h
M	source/blender/makesrna/intern/rna_lamp.c

===================================================================

diff --git a/release/scripts/startup/bl_ui/properties_data_lamp.py b/release/scripts/startup/bl_ui/properties_data_lamp.py
index 861ad81cdcc..40ebdbda75d 100644
--- a/release/scripts/startup/bl_ui/properties_data_lamp.py
+++ b/release/scripts/startup/bl_ui/properties_data_lamp.py
@@ -401,6 +401,19 @@ class DATA_PT_EEVEE_shadow(DataButtonsPanel, Panel):
             sub.prop(lamp, "shadow_cascade_max_distance", text="Max Distance")
             sub.prop(lamp, "shadow_cascade_exponent", text="Distribution")
 
+        layout.separator()
+
+        layout.prop(lamp, "use_contact_shadow")
+        split = layout.split()
+        split.active = lamp.use_contact_shadow
+        col = split.column()
+        col.prop(lamp, "contact_shadow_distance", text="Distance")
+        col.prop(lamp, "contact_shadow_soft_size", text="Soft")
+
+        col = split.column()
+        col.prop(lamp, "contact_shadow_bias", text="Bias")
+        col.prop(lamp, "contact_shadow_thickness", text="Thickness")
+
 
 class DATA_PT_area(DataButtonsPanel, Panel):
     bl_label = "Area Shape"
diff --git a/source/blender/blenkernel/intern/lamp.c b/source/blender/blenkernel/intern/lamp.c
index a9c85376a48..3d0d5f87f15 100644
--- a/source/blender/blenkernel/intern/lamp.c
+++ b/source/blender/blenkernel/intern/lamp.c
@@ -106,6 +106,10 @@ void BKE_lamp_init(Lamp *la)
 	la->cascade_count = 4;
 	la->cascade_exponent = 0.8f;
 	la->cascade_fade = 0.1f;
+	la->contact_dist = 1.0f;
+	la->contact_bias = 0.03f;
+	la->contact_spread = 0.2f;
+	la->contact_thickness = 0.5f;
 	
 	curvemapping_initialize(la->curfalloff);
 }
diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c
index f022b393967..bc011824c40 100644
--- a/source/blender/blenloader/intern/versioning_280.c
+++ b/source/blender/blenloader/intern/versioning_280.c
@@ -432,12 +432,23 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *main)
 		}
 	}
 
-	if (!DNA_struct_elem_find(fd->filesdna, "Lamp", "float", "cascade_max_dist"))	{
-		for (Lamp *la = main->lamp.first; la; la = la->id.next) {
-			la->cascade_max_dist = 1000.0f;
-			la->cascade_count = 4;
-			la->cascade_exponent = 0.8f;
-			la->cascade_fade = 0.1f;
+	{
+		if (!DNA_struct_elem_find(fd->filesdna, "Lamp", "float", "cascade_max_dist"))	{
+			for (Lamp *la = main->lamp.first; la; la = la->id.next) {
+				la->cascade_max_dist = 1000.0f;
+				la->cascade_count = 4;
+				la->cascade_exponent = 0.8f;
+				la->cascade_fade = 0.1f;
+			}
+		}
+
+		if (!DNA_struct_elem_find(fd->filesdna, "Lamp", "float", "contact_dist"))	{
+			for (Lamp *la = main->lamp.first; la; la = la->id.next) {
+				la->contact_dist = 1.0f;
+				la->contact_bias = 0.03f;
+				la->contact_spread = 0.2f;
+				la->contact_thickness = 0.5f;
+			}
 		}
 	}
 
diff --git a/source/blender/draw/engines/eevee/eevee_lights.c b/source/blender/draw/engines/eevee/eevee_lights.c
index 20344d46c50..8138b9a0ffd 100644
--- a/source/blender/draw/engines/eevee/eevee_lights.c
+++ b/source/blender/draw/engines/eevee/eevee_lights.c
@@ -509,6 +509,11 @@ static void eevee_shadow_cube_setup(Object *ob, EEVEE_LampsInfo *linfo, EEVEE_La
 	ubo_data->shadow_start = (float)(sh_data->layer_id);
 	ubo_data->data_start = (float)(sh_data->cube_id);
 	ubo_data->multi_shadow_count = (float)(sh_nbr);
+
+	ubo_data->contact_dist = (la->mode & LA_SHAD_CONTACT) ? la->contact_dist : 0.0f;
+	ubo_data->contact_bias = 0.05f * la->contact_bias;
+	ubo_data->contact_spread = la->contact_spread;
+	ubo_data->contact_thickness = la->contact_thickness;
 }
 
 #define LERP(t, a, b) ((a) + (t) * ((b) - (a)))
@@ -750,6 +755,11 @@ static void eevee_shadow_cascade_setup(Object *ob, EEVEE_LampsInfo *linfo, EEVEE
 	ubo_data->shadow_start = (float)(sh_data->layer_id);
 	ubo_data->data_start = (float)(sh_data->cascade_id);
 	ubo_data->multi_shadow_count = (float)(sh_nbr);
+
+	ubo_data->contact_dist = (la->mode & LA_SHAD_CONTACT) ? la->contact_dist : 0.0f;
+	ubo_data->contact_bias = 0.05f * la->contact_bias;
+	ubo_data->contact_spread = la->contact_spread;
+	ubo_data->contact_thickness = la->contact_thickness;
 }
 
 /* Used for checking if object is inside the shadow volume. */
diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h
index 392b4bfe24a..9d93097b7fd 100644
--- a/source/blender/draw/engines/eevee/eevee_private.h
+++ b/source/blender/draw/engines/eevee/eevee_private.h
@@ -221,6 +221,7 @@ typedef struct EEVEE_Light {
 typedef struct EEVEE_Shadow {
 	float near, far, bias, exp;
 	float shadow_start, data_start, multi_shadow_count, pad;
+	float contact_dist, contact_bias, contact_spread, contact_thickness;
 } EEVEE_Shadow;
 
 typedef struct EEVEE_ShadowCube {
diff --git a/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl b/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl
index c841acd3c23..3e0e36cad24 100644
--- a/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl
@@ -81,6 +81,7 @@ struct LightData {
 struct ShadowData {
 	vec4 near_far_bias_exp;
 	vec4 shadow_data_start_end;
+	vec4 contact_shadow_data;
 };
 
 struct ShadowCubeData {
@@ -102,6 +103,10 @@ struct ShadowCascadeData {
 #define sh_tex_start    shadow_data_start_end.x
 #define sh_data_start   shadow_data_start_end.y
 #define sh_multi_nbr    shadow_data_start_end.z
+#define sh_contact_dist            contact_shadow_data.x
+#define sh_contact_offset          contact_shadow_data.y
+#define sh_contact_spread          contact_shadow_data.z
+#define sh_contact_thickness       contact_shadow_data.w
 
 /* ------- Convenience functions --------- */
 
diff --git a/source/blender/draw/engines/eevee/shaders/lamps_lib.glsl b/source/blender/draw/engines/eevee/shaders/lamps_lib.glsl
index 676aa2c9748..a39f04d47af 100644
--- a/source/blender/draw/engines/eevee/shaders/lamps_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/lamps_lib.glsl
@@ -144,7 +144,7 @@ float shadow_cascade(ShadowData sd, ShadowCascadeData scd, float texid, vec3 W)
 /* ----------------------------------------------------------- */
 #define MAX_MULTI_SHADOW 4
 
-float light_visibility(LightData ld, vec3 W, vec4 l_vector)
+float light_visibility(LightData ld, vec3 W, vec3 viewPosition, vec3 viewNormal, vec4 l_vector)
 {
 	float vis = 1.0;
 
@@ -169,6 +169,7 @@ float light_visibility(LightData ld, vec3 W, vec4 l_vector)
 	/* shadowing */
 	if (ld.l_shadowid >= 0.0) {
 		ShadowData data = shadows_data[int(ld.l_shadowid)];
+
 		if (ld.l_type == SUN) {
 			/* TODO : MSM */
 			// for (int i = 0; i < MAX_MULTI_SHADOW; ++i) {
@@ -185,6 +186,35 @@ float light_visibility(LightData ld, vec3 W, vec4 l_vector)
 					data.sh_tex_start, W);
 			// }
 		}
+#endif
+
+#ifndef VOLUMETRICS
+		/* Only compute if not already in shadow. */
+		if ((vis > 0.001) && (data.sh_contact_dist > 0.0)) {
+			vec4 L = (ld.l_type != SUN) ? l_vector : vec4(-ld.l_forward, 1.0);
+			float trace_distance = (ld.l_type != SUN) ? min(data.sh_contact_dist, l_vector.w) : data.sh_contact_dist;
+
+			vec3 T, B;
+			make_orthonormal_basis(L.xyz / L.w, T, B);
+
+			vec3 rand = texture(utilTex, vec3(gl_FragCoord.xy / LUT_SIZE, 2.0)).xzw;
+			rand.yz *= rand.x * data.sh_contact_spread;
+
+			/* We use the full l_vector.xyz so that the spread is minimize
+			 * if the shading point is further away from the light source */
+			vec3 ray_dir = L.xyz + T * rand.y + B * rand.z;
+			ray_dir = transform_direction(ViewMatrix, ray_dir);
+			ray_dir = normalize(ray_dir);
+			vec3 ray_origin = viewPosition + viewNormal * data.sh_contact_offset;
+			vec3 hit_pos = raycast(-1, ray_origin, ray_dir * trace_distance, data.sh_contact_thickness, rand.x, 0.75, 0.01);
+
+			if (hit_pos.z > 0.0) {
+				hit_pos = get_view_space_from_depth(hit_pos.xy, hit_pos.z);
+				float hit_dist = distance(viewPosition, hit_pos);
+				float dist_ratio = hit_dist / trace_distance;
+				return mix(0.0, vis, dist_ratio * dist_ratio * dist_ratio);
+			}
+		}
 	}
 #endif
 
diff --git a/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl b/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl
index 5f4a4c9f89f..f63a9665810 100644
--- a/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl
@@ -66,7 +66,7 @@ vec3 eevee_surface_lit(vec3 N, vec3 albedo, vec3 f0, float roughness, float ao,
 		l_vector.xyz = ld.l_position - worldPosition;
 		l_vector.w = length(l_vector.xyz);
 
-		vec3 l_color_vis = ld.l_color * light_visibility(ld, worldPosition, l_vector);
+		vec3 l_color_vis = ld.l_color * light_visibility(ld, worldPosition, viewPosition, viewNormal, l_vector);
 
 #ifdef HAIR_SHADER
 		vec3 norm_lamp, view_vec;
@@ -224,7 +224,7 @@ vec3 eevee_surface_clearcoat_lit(
 		l_vector.xyz = ld.l_position - worldPosition;
 		l_vector.w = length(l_vector.xyz);
 
-		vec3 l_color_vis = ld.l_color * light_visibility(ld, worldPosition, l_vector);
+		vec3 l_color_vis = ld.l_color * light_visibility(ld, worldPosition, viewPosition, viewNormal, l_vector);
 
 #ifdef HAIR_SHADER
 		vec3 norm_lamp, view_vec;
@@ -388,7 +388,7 @@ vec3 eevee_surface_diffuse_lit(vec3 N, vec3 albedo, float ao)
 		l_vector.xyz = ld.l_position - worldPosition;
 		l_vector.w = length(l_vector.xyz);
 
-		vec3 l_color_vis = ld.l_color * light_visibility(ld, worldPosition, l_vector);
+		vec3 l_color_vis = ld.l_color * light_visibility(ld, worldPosition, viewPosition, viewNormal, l_vector);
 
 #ifdef HAIR_SHADER
 		vec3 norm_lamp, view_vec;
@@ -480,7 +480,7 @@ vec3 eevee_surface_glossy_lit(vec3 N, vec3 f0, float roughness, float ao, int ss
 		l_vector.xyz = ld.l_position - worldPosition;
 		l_vector.w = length(l_vector.xyz);
 
-		vec3 l_color_vis = ld.l_color * light_visibility(ld, worldPosition, l_vector);
+		vec3 l_color_vis = ld.l_color * light_visibility(ld, worldPosition, viewPosition, viewNormal, l_vector);
 
 #ifdef HAIR_SHADER
 		vec3 norm_lamp, view_vec;
@@ -681,7 +681,7 @@ vec3 eevee_surface_glass(vec3 N, vec3 transmission_col, float roughness, float i
 		l_vector.xyz = ld.l_position - worldPosition;
 		l_vector.w = length(l_vector.xy

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list