[Bf-blender-cvs] [716f7859a8f] blender2.8: Eevee: Add Cascaded Shadow Map support with filtering.

Clément Foucault noreply at git.blender.org
Sun Sep 10 03:16:48 CEST 2017


Commit: 716f7859a8f1412a656b51269ee82d46a2d8c7ae
Author: Clément Foucault
Date:   Tue Sep 5 21:02:17 2017 +0200
Branches: blender2.8
https://developer.blender.org/rB716f7859a8f1412a656b51269ee82d46a2d8c7ae

Eevee: Add Cascaded Shadow Map support with filtering.

This brings some data structure changes.
Shared shadow data are stored in ShadowData (in glsl) (aka EEVEE_Shadow in C).
This structure contains the array indices of the first shadow element of this shadow "object".
It also contains how many shadow to evaluate (to be used for Multiple shadow maps).

The filtering is noisy and needs improvement.

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

M	release/scripts/startup/bl_ui/properties_data_lamp.py
M	source/blender/draw/engines/eevee/eevee_lights.c
M	source/blender/draw/engines/eevee/eevee_materials.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/shadow_geom.glsl
M	source/blender/draw/engines/eevee/shaders/shadow_store_frag.glsl

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

diff --git a/release/scripts/startup/bl_ui/properties_data_lamp.py b/release/scripts/startup/bl_ui/properties_data_lamp.py
index c9b5fa80122..39b5f0eba55 100644
--- a/release/scripts/startup/bl_ui/properties_data_lamp.py
+++ b/release/scripts/startup/bl_ui/properties_data_lamp.py
@@ -371,23 +371,20 @@ class DATA_PT_EEVEE_shadow(DataButtonsPanel, Panel):
 
         lamp = context.lamp
 
-        if lamp.type == 'SUN':
-            layout.label("Comming Soon")
-        else:
-            split = layout.split()
-            split.active = lamp.use_shadow
-
-            sub = split.column()
-            col = sub.column(align=True)
-            col.prop(lamp, "shadow_buffer_clip_start", text="Clip Start")
-            col.prop(lamp, "shadow_buffer_clip_end", text="Clip End")
-            col = sub.column()
-            col.prop(lamp, "shadow_buffer_soft", text="Soft")
-
-            col = split.column(align=True)
-            col.prop(lamp, "shadow_buffer_bias", text="Bias")
-            col.prop(lamp, "shadow_buffer_exp", text="Exponent")
-            col.prop(lamp, "shadow_buffer_bleed_bias", text="Bleed Bias")
+        split = layout.split()
+        split.active = lamp.use_shadow
+
+        sub = split.column()
+        col = sub.column(align=True)
+        col.prop(lamp, "shadow_buffer_clip_start", text="Clip Start")
+        col.prop(lamp, "shadow_buffer_clip_end", text="Clip End")
+        col = sub.column()
+        col.prop(lamp, "shadow_buffer_soft", text="Soft")
+
+        col = split.column(align=True)
+        col.prop(lamp, "shadow_buffer_bias", text="Bias")
+        col.prop(lamp, "shadow_buffer_exp", text="Exponent")
+        col.prop(lamp, "shadow_buffer_bleed_bias", text="Bleed Bias")
 
 
 class DATA_PT_area(DataButtonsPanel, Panel):
diff --git a/source/blender/draw/engines/eevee/eevee_lights.c b/source/blender/draw/engines/eevee/eevee_lights.c
index 0033670528a..2bd33f0a755 100644
--- a/source/blender/draw/engines/eevee/eevee_lights.c
+++ b/source/blender/draw/engines/eevee/eevee_lights.c
@@ -38,13 +38,13 @@ typedef struct EEVEE_LightData {
 } EEVEE_LightData;
 
 typedef struct EEVEE_ShadowCubeData {
-	short light_id, shadow_id;
-	float viewprojmat[6][4][4];
+	short light_id, shadow_id, cube_id, layer_id;
 } EEVEE_ShadowCubeData;
 
 typedef struct EEVEE_ShadowCascadeData {
-	short light_id, shadow_id;
+	short light_id, shadow_id, cascade_id, layer_id;
 	float viewprojmat[MAX_CASCADE_NUM][4][4]; /* World->Lamp->NDC : used for rendering the shadow map. */
+	float radius[MAX_CASCADE_NUM];
 } EEVEE_ShadowCascadeData;
 
 typedef struct ShadowCaster {
@@ -68,7 +68,8 @@ extern char datatoc_shadow_store_frag_glsl[];
 
 void EEVEE_lights_init(EEVEE_SceneLayerData *sldata)
 {
-	const unsigned int shadow_ubo_size = sizeof(EEVEE_ShadowCube) * MAX_SHADOW_CUBE +
+	const unsigned int shadow_ubo_size = sizeof(EEVEE_Shadow) * MAX_SHADOW +
+	                                     sizeof(EEVEE_ShadowCube) * MAX_SHADOW_CUBE +
 	                                     sizeof(EEVEE_ShadowCascade) * MAX_SHADOW_CASCADE;
 
 	const DRWContextState *draw_ctx = DRW_context_state_get();
@@ -130,7 +131,10 @@ void EEVEE_lights_cache_init(EEVEE_SceneLayerData *sldata, EEVEE_PassList *psl)
 {
 	EEVEE_LampsInfo *linfo = sldata->lamps;
 
-	linfo->num_light = linfo->num_cube = linfo->num_cascade = linfo->num_shadow = 0;
+	linfo->num_light = 0;
+	linfo->num_layer = 0;
+	linfo->gpu_cube_ct = linfo->gpu_cascade_ct = linfo->gpu_shadow_ct = 0;
+	linfo->cpu_cube_ct = linfo->cpu_cascade_ct = 0;
 	memset(linfo->light_ref, 0, sizeof(linfo->light_ref));
 	memset(linfo->shadow_cube_ref, 0, sizeof(linfo->shadow_cube_ref));
 	memset(linfo->shadow_cascade_ref, 0, sizeof(linfo->shadow_cascade_ref));
@@ -141,6 +145,7 @@ void EEVEE_lights_cache_init(EEVEE_SceneLayerData *sldata, EEVEE_PassList *psl)
 		DRWShadingGroup *grp = DRW_shgroup_create(e_data.shadow_store_cube_sh[linfo->shadow_method], psl->shadow_cube_store_pass);
 		DRW_shgroup_uniform_buffer(grp, "shadowTexture", &sldata->shadow_cube_target);
 		DRW_shgroup_uniform_block(grp, "shadow_render_block", sldata->shadow_render_ubo);
+		DRW_shgroup_uniform_float(grp, "shadowFilterSize", &linfo->filter_size, 1);
 		DRW_shgroup_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL);
 	}
 
@@ -150,6 +155,8 @@ void EEVEE_lights_cache_init(EEVEE_SceneLayerData *sldata, EEVEE_PassList *psl)
 		DRWShadingGroup *grp = DRW_shgroup_create(e_data.shadow_store_cascade_sh[linfo->shadow_method], psl->shadow_cascade_store_pass);
 		DRW_shgroup_uniform_buffer(grp, "shadowTexture", &sldata->shadow_cascade_target);
 		DRW_shgroup_uniform_block(grp, "shadow_render_block", sldata->shadow_render_ubo);
+		DRW_shgroup_uniform_int(grp, "cascadeId", &linfo->current_shadow_cascade, 1);
+		DRW_shgroup_uniform_float(grp, "shadowFilterSize", &linfo->filter_size, 1);
 		DRW_shgroup_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL);
 	}
 
@@ -184,28 +191,54 @@ void EEVEE_lights_cache_add(EEVEE_SceneLayerData *sldata, Object *ob)
 
 		MEM_SAFE_FREE(led->storage);
 
-#if 1 /* TODO Waiting for notified refresh. only on scene change. Else too much perf cost. */
 		if (la->mode & (LA_SHAD_BUF | LA_SHAD_RAY)) {
-			if (la->type == LA_SUN && linfo->num_cascade < MAX_SHADOW_CASCADE) {
-				led->storage = MEM_mallocN(sizeof(EEVEE_ShadowCascadeData), "EEVEE_ShadowCascadeData");
-				((EEVEE_ShadowCascadeData *)led->storage)->shadow_id = linfo->num_shadow;
-				linfo->shadow_cascade_ref[linfo->num_cascade] = ob;
-				linfo->num_cascade++;
-				linfo->num_shadow += MAX_CASCADE_NUM;
+			if (la->type == LA_SUN)	{
+				int sh_nbr = 1; /* TODO : MSM */
+				int cascade_nbr = MAX_CASCADE_NUM; /* TODO : Custom cascade number */
+
+				if ((linfo->gpu_cascade_ct + sh_nbr) <= MAX_SHADOW_CASCADE) {
+					/* Save Light object. */
+					linfo->shadow_cascade_ref[linfo->cpu_cascade_ct] = ob;
+
+					/* Create storage and store indices. */
+					EEVEE_ShadowCascadeData *data = MEM_mallocN(sizeof(EEVEE_ShadowCascadeData), "EEVEE_ShadowCascadeData");
+					data->shadow_id = linfo->gpu_shadow_ct;
+					data->cascade_id = linfo->gpu_cascade_ct;
+					data->layer_id = linfo->num_layer;
+					led->storage = data;
+
+					/* Increment indices. */
+					linfo->gpu_shadow_ct += 1;
+					linfo->gpu_cascade_ct += sh_nbr;
+					linfo->num_layer += sh_nbr * cascade_nbr;
+
+					linfo->cpu_cascade_ct += 1;
+				}
 			}
-			else if ((la->type == LA_SPOT || la->type == LA_LOCAL || la->type == LA_AREA)
-			          && linfo->num_cube < MAX_SHADOW_CUBE) {
-				led->storage = MEM_mallocN(sizeof(EEVEE_ShadowCubeData), "EEVEE_ShadowCubeData");
-				((EEVEE_ShadowCubeData *)led->storage)->shadow_id = linfo->num_shadow;
-				linfo->shadow_cube_ref[linfo->num_cube] = ob;
-				linfo->num_cube++;
-				linfo->num_shadow += 1;
+			else if (la->type == LA_SPOT || la->type == LA_LOCAL || la->type == LA_AREA) {
+				int sh_nbr = 1; /* TODO : MSM */
+
+				if ((linfo->gpu_cube_ct + sh_nbr) <= MAX_SHADOW_CUBE) {
+					/* Save Light object. */
+					linfo->shadow_cube_ref[linfo->cpu_cube_ct] = ob;
+
+					/* Create storage and store indices. */
+					EEVEE_ShadowCubeData *data = MEM_mallocN(sizeof(EEVEE_ShadowCubeData), "EEVEE_ShadowCubeData");
+					data->shadow_id = linfo->gpu_shadow_ct;
+					data->cube_id = linfo->gpu_cube_ct;
+					data->layer_id = linfo->num_layer;
+					led->storage = data;
+
+					/* Increment indices. */
+					linfo->gpu_shadow_ct += 1;
+					linfo->gpu_cube_ct += sh_nbr;
+					linfo->num_layer += sh_nbr;
+
+					linfo->cpu_cube_ct += 1;
+				}
 			}
-
 		}
-#else
-		UNUSED_VARS(la);
-#endif
+
 		/* Default light without shadows */
 		if (!led->storage) {
 			led->storage = MEM_mallocN(sizeof(EEVEE_LightData), "EEVEE_LightData");
@@ -270,14 +303,9 @@ void EEVEE_lights_cache_finish(EEVEE_SceneLayerData *sldata)
 
 	/* Setup enough layers. */
 	/* Free textures if number mismatch. */
-	if ((linfo->num_shadow != linfo->cache_num_shadow) ||
-		(linfo->num_cube != linfo->cache_num_cube) ||
-	    (linfo->num_cascade != linfo->cache_num_cascade))
-	{
+	if (linfo->num_layer != linfo->cache_num_layer) {
 		DRW_TEXTURE_FREE_SAFE(sldata->shadow_pool);
-		linfo->cache_num_cube = linfo->num_cube;
-		linfo->cache_num_cascade = linfo->num_cascade;
-		linfo->cache_num_shadow = linfo->num_shadow;
+		linfo->cache_num_layer = linfo->num_layer;
 		linfo->update_flag |= LIGHT_UPDATE_SHADOW_CUBE;
 	}
 
@@ -305,7 +333,7 @@ void EEVEE_lights_cache_finish(EEVEE_SceneLayerData *sldata)
 	if (!sldata->shadow_pool) {
 		/* All shadows fit in this array */
 		sldata->shadow_pool = DRW_texture_create_2D_array(
-		        linfo->shadow_size, linfo->shadow_size, max_ff(1, linfo->num_cube + linfo->num_cascade),
+		        linfo->shadow_size, linfo->shadow_size, max_ff(1, linfo->num_layer),
 		        shadow_pool_format, DRW_TEX_FILTER, NULL);
 	}
 
@@ -405,29 +433,28 @@ static void eevee_light_setup(Object *ob, EEVEE_LampsInfo *linfo, EEVEE_LampEngi
 
 static void eevee_shadow_cube_setup(Object *ob, EEVEE_LampsInfo *linfo, EEVEE_LampEngineData *led)
 {
-	float projmat[4][4];
-
-	EEVEE_ShadowCubeData *evsmp = (EEVEE_ShadowCubeData *)led->storage;
-	EEVEE_Light *evli = linfo->light_data + evsmp->light_id;
-	EEVEE_ShadowCube *evsh = linfo->shadow_cube_data + evsmp->shadow_id;
+	EEVEE_ShadowCubeData *sh_data = (EEVEE_ShadowCubeData *)led->storage;
+	EEVEE_Light *evli = linfo->light_data + sh_data->light_id;
+	EEVEE_Shadow *ubo_data = linfo->shadow_data + sh_data->shadow_id;
+	EEVEE_ShadowCube *cube_data = linfo->shadow_cube_data + sh_data->cube_id;
 	Lamp *la = (Lamp *)ob->data;
 
-	perspective_m4(projmat, -la->clipsta, la->clipsta, -la->clipsta, la->clipsta, la->clipsta, la->clipend);
+	int sh_nbr = 1; /* TODO: MSM */
 
-	for (int i = 0; i < 6; ++i) {
-		float tmp[4][4];
-		unit_m4(tmp);
-		negate_v3_v3(tmp[3], ob->obmat[3]);
-		mul_m4_m4m4(tmp, cubefacemat[i], tmp);
-		mul_m4_m4m4(evsmp->viewprojmat[i], projmat, tmp);
+	for (int i = 0; i < sh_nbr; ++i) {
+		/* TODO : choose MSM sample point here. */
+		copy_v3_v3(cube_data->position, ob->obmat[3]);
 	}
 
-	evsh->bias = 0.05f * la->bias;
-	evsh->near = la->clipsta;
-	evsh->far = la->clipend;
-	evsh->exp = (linfo->shadow_method == SHADOW_VSM) ? la->bleedbias : la->bleedexp;
+	ubo_

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list