[Bf-blender-cvs] [c43d51c1c2c] blender2.8: Eevee: Make use of culling when rendering the shadowmaps.

Clément Foucault noreply at git.blender.org
Fri Mar 2 18:32:37 CET 2018


Commit: c43d51c1c2c7c811a30a26ebc1fcdf7af6c0c0c0
Author: Clément Foucault
Date:   Fri Mar 2 18:35:25 2018 +0100
Branches: blender2.8
https://developer.blender.org/rBc43d51c1c2c7c811a30a26ebc1fcdf7af6c0c0c0

Eevee: Make use of culling when rendering the shadowmaps.

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

M	source/blender/draw/engines/eevee/eevee_lightprobes.c
M	source/blender/draw/engines/eevee/eevee_lights.c
M	source/blender/draw/engines/eevee/eevee_private.h

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

diff --git a/source/blender/draw/engines/eevee/eevee_lightprobes.c b/source/blender/draw/engines/eevee/eevee_lightprobes.c
index b69823b60c3..11eebb517e2 100644
--- a/source/blender/draw/engines/eevee/eevee_lightprobes.c
+++ b/source/blender/draw/engines/eevee/eevee_lightprobes.c
@@ -1246,13 +1246,13 @@ static void render_scene_to_planar(
 	DRW_viewport_matrix_override_set(viewmat, DRW_MAT_VIEW);
 	DRW_viewport_matrix_override_set(viewinv, DRW_MAT_VIEWINV);
 
+	/* Be sure that cascaded shadow maps are updated. */
+	EEVEE_draw_shadows(sldata, psl);
+
 	/* Since we are rendering with an inverted view matrix, we need
 	 * to invert the facing for backface culling to be the same. */
 	DRW_state_invert_facing();
 
-	/* Be sure that cascaded shadow maps are updated. */
-	EEVEE_draw_shadows(sldata, psl);
-
 	DRW_state_clip_planes_add(clip_plane);
 
 	/* Attach depth here since it's a DRW_TEX_TEMP */
diff --git a/source/blender/draw/engines/eevee/eevee_lights.c b/source/blender/draw/engines/eevee/eevee_lights.c
index 9eb6a761e1d..622c7bc95d5 100644
--- a/source/blender/draw/engines/eevee/eevee_lights.c
+++ b/source/blender/draw/engines/eevee/eevee_lights.c
@@ -26,6 +26,7 @@
 #include "DRW_render.h"
 
 #include "BLI_dynstr.h"
+#include "BLI_rect.h"
 
 #include "BKE_object.h"
 
@@ -710,7 +711,7 @@ static void eevee_shadow_cascade_setup(Object *ob, EEVEE_LampsInfo *linfo, EEVEE
 	}
 
 	/* Lamps Matrices */
-	float viewmat[4][4], projmat[4][4];
+	float (*viewmat)[4], projmat[4][4];
 	int sh_nbr = 1; /* TODO : MSM */
 	int cascade_nbr = la->cascade_count;
 
@@ -719,6 +720,13 @@ static void eevee_shadow_cascade_setup(Object *ob, EEVEE_LampsInfo *linfo, EEVEE
 	EEVEE_Shadow *ubo_data = linfo->shadow_data + sh_data->shadow_id;
 	EEVEE_ShadowCascade *cascade_data = linfo->shadow_cascade_data + sh_data->cascade_id;
 
+	/* obmat = Object Space > World Space */
+	/* viewmat = World Space > View Space */
+	invert_m4_m4(sh_data->clipmat[DRW_MAT_VIEW], ob->obmat);
+	viewmat = sh_data->clipmat[DRW_MAT_VIEW];
+	normalize_m4(viewmat);
+	invert_m4_m4(sh_data->clipmat[DRW_MAT_VIEWINV], viewmat);
+
 	/* The technique consists into splitting
 	 * the view frustum into several sub-frustum
 	 * that are individually receiving one shadow map */
@@ -817,6 +825,7 @@ static void eevee_shadow_cascade_setup(Object *ob, EEVEE_LampsInfo *linfo, EEVEE
 	cascade_data->split_start[0] = LERP(la->cascade_fade, cascade_data->split_end[cascade_nbr - 1], prev_split);
 
 	/* For each cascade */
+	rctf rect_clip, rect_cascade;
 	for (int c = 0; c < cascade_nbr; ++c) {
 		/* Given 8 frustum corners */
 		float corners[8][3] = {
@@ -841,11 +850,6 @@ static void eevee_shadow_cascade_setup(Object *ob, EEVEE_LampsInfo *linfo, EEVEE
 		frustum_min_bounding_sphere(corners, center, &(sh_data->radius[c]));
 
 		/* Project into lightspace */
-		invert_m4_m4(viewmat, ob->obmat);
-		normalize_v3(viewmat[0]);
-		normalize_v3(viewmat[1]);
-		normalize_v3(viewmat[2]);
-
 		mul_mat3_m4_v3(viewmat, center);
 
 		/* Snap projection center to nearest texel to cancel shimmering. */
@@ -865,17 +869,32 @@ static void eevee_shadow_cascade_setup(Object *ob, EEVEE_LampsInfo *linfo, EEVEE
 		add_v2_v2(center, shadow_texco);
 
 		/* Expand the projection to cover frustum range */
+		BLI_rctf_init_pt_radius(&rect_cascade, center, sh_data->radius[c]);
 		orthographic_m4(projmat,
-		                center[0] - sh_data->radius[c],
-		                center[0] + sh_data->radius[c],
-		                center[1] - sh_data->radius[c],
-		                center[1] + sh_data->radius[c],
+		                rect_cascade.xmin, rect_cascade.xmax,
+		                rect_cascade.ymin, rect_cascade.ymax,
 		                la->clipsta, la->clipend);
 
+		if (c == 0) {
+			memcpy(&rect_clip, &rect_cascade, sizeof(rect_clip));
+		}
+		else {
+			BLI_rctf_union(&rect_clip, &rect_cascade);
+		}
+
 		mul_m4_m4m4(sh_data->viewprojmat[c], projmat, viewmat);
 		mul_m4_m4m4(cascade_data->shadowmat[c], texcomat, sh_data->viewprojmat[c]);
 	}
 
+	/* Clipping mats */
+	orthographic_m4(sh_data->clipmat[DRW_MAT_WIN],
+	                rect_clip.xmin, rect_clip.xmax,
+	                rect_clip.ymin, rect_clip.ymax,
+	                la->clipsta, la->clipend);
+	mul_m4_m4m4(sh_data->clipmat[DRW_MAT_PERS], sh_data->clipmat[DRW_MAT_WIN], viewmat);
+	invert_m4_m4(sh_data->clipmat[DRW_MAT_WININV], sh_data->clipmat[DRW_MAT_WIN]);
+	invert_m4_m4(sh_data->clipmat[DRW_MAT_PERSINV], sh_data->clipmat[DRW_MAT_PERS]);
+
 	ubo_data->bias = 0.05f * la->bias;
 	ubo_data->near = la->clipsta;
 	ubo_data->far = la->clipend;
@@ -977,6 +996,37 @@ void EEVEE_lights_update(EEVEE_ViewLayerData *sldata)
 	}
 }
 
+static void eevee_shadows_cube_culling_frustum(EEVEE_ShadowRender *srd)
+{
+	float persmat[4][4], persinv[4][4];
+	float viewmat[4][4], viewinv[4][4];
+	float winmat[4][4], wininv[4][4];
+	orthographic_m4(winmat, -srd->clip_far, srd->clip_far, -srd->clip_far, srd->clip_far, -srd->clip_far, srd->clip_far);
+	DRW_viewport_matrix_override_set(winmat, DRW_MAT_WIN);
+
+	invert_m4_m4(wininv, winmat);
+	DRW_viewport_matrix_override_set(wininv, DRW_MAT_WININV);
+
+	unit_m4(viewmat);
+	negate_v3_v3(viewmat[3], srd->position);
+	DRW_viewport_matrix_override_set(viewmat, DRW_MAT_VIEW);
+
+	unit_m4(viewinv);
+	copy_v3_v3(viewinv[3], srd->position);
+	DRW_viewport_matrix_override_set(viewinv, DRW_MAT_VIEWINV);
+
+	mul_m4_m4m4(persmat, winmat, viewmat);
+	DRW_viewport_matrix_override_set(persmat, DRW_MAT_PERS);
+
+	invert_m4_m4(persinv, persmat);
+	DRW_viewport_matrix_override_set(persinv, DRW_MAT_PERSINV);
+}
+
+static void eevee_shadows_cascade_culling_frustum(EEVEE_ShadowCascadeData *evscd)
+{
+	DRW_viewport_matrix_override_set_all((DRWMatrixState *)evscd->clipmat);
+}
+
 /* this refresh lamps shadow buffers */
 void EEVEE_draw_shadows(EEVEE_ViewLayerData *sldata, EEVEE_PassList *psl)
 {
@@ -985,6 +1035,11 @@ void EEVEE_draw_shadows(EEVEE_ViewLayerData *sldata, EEVEE_PassList *psl)
 	int i;
 	float clear_col[4] = {FLT_MAX};
 
+	DRWMatrixState saved_mats;
+
+	/* We need to save the Matrices before overidding them */
+	DRW_viewport_matrix_get_all(&saved_mats);
+
 	/* Cube Shadow Maps */
 	DRW_stats_group_start("Cube Shadow Maps");
 	DRW_framebuffer_texture_attach(sldata->shadow_target_fb, sldata->shadow_cube_target, 0, 0);
@@ -993,9 +1048,6 @@ void EEVEE_draw_shadows(EEVEE_ViewLayerData *sldata, EEVEE_PassList *psl)
 		EEVEE_LampEngineData *led = EEVEE_lamp_data_ensure(ob);
 		Lamp *la = (Lamp *)ob->data;
 
-		float cube_projmat[4][4];
-		perspective_m4(cube_projmat, -la->clipsta, la->clipsta, -la->clipsta, la->clipsta, la->clipsta, la->clipend);
-
 		if (!led->need_update) {
 			continue;
 		}
@@ -1003,20 +1055,24 @@ void EEVEE_draw_shadows(EEVEE_ViewLayerData *sldata, EEVEE_PassList *psl)
 		EEVEE_ShadowRender *srd = &linfo->shadow_render_data;
 		EEVEE_ShadowCubeData *evscd = &led->data.scd;
 
+		float cube_projmat[4][4];
+		float cube_viewmat[4][4];
+		perspective_m4(cube_projmat, -la->clipsta, la->clipsta, -la->clipsta, la->clipsta, la->clipsta, la->clipend);
+		unit_m4(cube_viewmat);
+
 		srd->clip_near = la->clipsta;
 		srd->clip_far = la->clipend;
 		copy_v3_v3(srd->position, ob->obmat[3]);
-		for (int j = 0; j < 6; j++) {
-			float tmp[4][4];
-
-			unit_m4(tmp);
-			negate_v3_v3(tmp[3], ob->obmat[3]);
-			mul_m4_m4m4(srd->viewmat[j], cubefacemat[j], tmp);
 
+		negate_v3_v3(cube_viewmat[3], srd->position);
+		for (int j = 0; j < 6; j++) {
+			mul_m4_m4m4(srd->viewmat[j], cubefacemat[j], cube_viewmat);
 			mul_m4_m4m4(srd->shadowmat[j], cube_projmat, srd->viewmat[j]);
 		}
 		DRW_uniformbuffer_update(sldata->shadow_render_ubo, srd);
 
+		eevee_shadows_cube_culling_frustum(srd);
+
 		DRW_framebuffer_bind(sldata->shadow_target_fb);
 		DRW_framebuffer_clear(true, true, false, clear_col, 1.0f);
 
@@ -1095,6 +1151,8 @@ void EEVEE_draw_shadows(EEVEE_ViewLayerData *sldata, EEVEE_PassList *psl)
 		DRW_framebuffer_bind(sldata->shadow_target_fb);
 		DRW_framebuffer_clear(false, true, false, NULL, 1.0);
 
+		eevee_shadows_cascade_culling_frustum(evscd);
+
 		/* Render shadow cascades */
 		linfo->shadow_instance_count = la->cascade_count;
 		DRW_draw_pass(psl->shadow_pass);
@@ -1147,6 +1205,8 @@ void EEVEE_draw_shadows(EEVEE_ViewLayerData *sldata, EEVEE_PassList *psl)
 	DRW_framebuffer_texture_detach(sldata->shadow_cascade_target);
 	DRW_stats_group_end();
 
+	DRW_viewport_matrix_override_set_all(&saved_mats);
+
 	DRW_uniformbuffer_update(sldata->light_ubo, &linfo->light_data);
 	DRW_uniformbuffer_update(sldata->shadow_ubo, &linfo->shadow_data); /* Update all data at once */
 }
diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h
index fa23d6f72ef..8b035e97bf4 100644
--- a/source/blender/draw/engines/eevee/eevee_private.h
+++ b/source/blender/draw/engines/eevee/eevee_private.h
@@ -655,6 +655,7 @@ typedef struct EEVEE_ShadowCubeData {
 typedef struct EEVEE_ShadowCascadeData {
 	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 clipmat[DRW_MAT_COUNT][4][4]; /* Override matrices used for clipping. */
 	float radius[MAX_CASCADE_NUM];
 } EEVEE_ShadowCascadeData;



More information about the Bf-blender-cvs mailing list