[Bf-blender-cvs] [b795f5eb7a9] blender2.8: Eevee: Cleanup cascaded shadowmap code.

Clément Foucault noreply at git.blender.org
Mon Feb 26 18:32:48 CET 2018


Commit: b795f5eb7a913f2fb86667098c36e8f654a9ef6a
Author: Clément Foucault
Date:   Sat Feb 24 04:25:25 2018 +0100
Branches: blender2.8
https://developer.blender.org/rBb795f5eb7a913f2fb86667098c36e8f654a9ef6a

Eevee: Cleanup cascaded shadowmap code.

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

M	source/blender/draw/engines/eevee/eevee_lights.c

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

diff --git a/source/blender/draw/engines/eevee/eevee_lights.c b/source/blender/draw/engines/eevee/eevee_lights.c
index 582f7ea747a..3db7d893f2d 100644
--- a/source/blender/draw/engines/eevee/eevee_lights.c
+++ b/source/blender/draw/engines/eevee/eevee_lights.c
@@ -653,9 +653,15 @@ static void eevee_shadow_cube_setup(Object *ob, EEVEE_LampsInfo *linfo, EEVEE_La
 
 #define LERP(t, a, b) ((a) + (t) * ((b) - (a)))
 
-static void frustum_min_bounding_sphere(const float corners[8][4], float r_center[3], float *r_radius)
+static double round_to_digits(double value, int digits)
 {
-#if 0 /* Simple solution but waist too much space. */
+	double factor = pow(10.0, digits - ceil(log10(fabs(value))));
+	return round(value * factor) / factor;
+}
+
+static void frustum_min_bounding_sphere(const float corners[8][3], float r_center[3], float *r_radius)
+{
+#if 0 /* Simple solution but waste too much space. */
 	float minvec[3], maxvec[3];
 
 	/* compute the bounding box */
@@ -669,19 +675,27 @@ static void frustum_min_bounding_sphere(const float corners[8][4], float r_cente
 	add_v3_v3v3(r_center, minvec, maxvec);
 	mul_v3_fl(r_center, 0.5f);
 #else
-	/* Make the bouding sphere always centered on the front diagonal */
-	add_v3_v3v3(r_center, corners[4], corners[7]);
-	mul_v3_fl(r_center, 0.5f);
-	*r_radius = len_v3v3(corners[0], r_center);
+	/* Find averaged center. */
+	zero_v3(r_center);
+	for (int i = 0; i < 8; ++i) {
+		add_v3_v3(r_center, corners[i]);
+	}
+	mul_v3_fl(r_center, 1.0f / 8.0f);
 
-	/* Search the largest distance between the sphere center
-	 * and the front plane corners. */
-	for (int i = 0; i < 4; ++i) {
-		float rad = len_v3v3(corners[4 + i], r_center);
+	/* Search the largest distance from the sphere center. */
+	*r_radius = 0.0f;
+	for (int i = 0; i < 8; ++i) {
+		float rad = len_squared_v3v3(corners[i], r_center);
 		if (rad > *r_radius) {
 			*r_radius = rad;
 		}
 	}
+
+	/* TODO try to reduce the radius further by moving the center.
+	 * Remember we need a __stable__ solution! */
+
+	/* Try to reduce float imprecision leading to shimmering. */
+	*r_radius = (float)round_to_digits(sqrtf(*r_radius), 3);
 #endif
 }
 
@@ -820,39 +834,36 @@ static void eevee_shadow_cascade_setup(Object *ob, EEVEE_LampsInfo *linfo, EEVEE
 	/* For each cascade */
 	for (int c = 0; c < cascade_nbr; ++c) {
 		/* Given 8 frustum corners */
-		float corners[8][4] = {
+		float corners[8][3] = {
 			/* Near Cap */
-			{-1.0f, -1.0f, splits_start_ndc[c], 1.0f},
-			{ 1.0f, -1.0f, splits_start_ndc[c], 1.0f},
-			{-1.0f,  1.0f, splits_start_ndc[c], 1.0f},
-			{ 1.0f,  1.0f, splits_start_ndc[c], 1.0f},
+			{-1.0f, -1.0f, splits_start_ndc[c]},
+			{ 1.0f, -1.0f, splits_start_ndc[c]},
+			{-1.0f,  1.0f, splits_start_ndc[c]},
+			{ 1.0f,  1.0f, splits_start_ndc[c]},
 			/* Far Cap */
-			{-1.0f, -1.0f, splits_end_ndc[c], 1.0f},
-			{ 1.0f, -1.0f, splits_end_ndc[c], 1.0f},
-			{-1.0f,  1.0f, splits_end_ndc[c], 1.0f},
-			{ 1.0f,  1.0f, splits_end_ndc[c], 1.0f}
+			{-1.0f, -1.0f, splits_end_ndc[c]},
+			{ 1.0f, -1.0f, splits_end_ndc[c]},
+			{-1.0f,  1.0f, splits_end_ndc[c]},
+			{ 1.0f,  1.0f, splits_end_ndc[c]}
 		};
 
 		/* Transform them into world space */
 		for (int i = 0; i < 8; ++i) {
-			mul_m4_v4(persinv, corners[i]);
-			mul_v3_fl(corners[i], 1.0f / corners[i][3]);
-			corners[i][3] = 1.0f;
+			mul_project_m4_v3(persinv, corners[i]);
 		}
 
+		float center[3];
+		frustum_min_bounding_sphere(corners, center, &(sh_data->radius[c]));
 
-		/* Project them into light space */
+		printf("\n");
+
+		/* Project into lightspace */
 		invert_m4_m4(viewmat, ob->obmat);
 		normalize_v3(viewmat[0]);
 		normalize_v3(viewmat[1]);
 		normalize_v3(viewmat[2]);
 
-		for (int i = 0; i < 8; ++i) {
-			mul_m4_v4(viewmat, corners[i]);
-		}
-
-		float center[3];
-		frustum_min_bounding_sphere(corners, center, &(sh_data->radius[c]));
+		mul_mat3_m4_v3(viewmat, center);
 
 		/* Snap projection center to nearest texel to cancel shimmering. */
 		float shadow_origin[2], shadow_texco[2];
@@ -860,8 +871,8 @@ static void eevee_shadow_cascade_setup(Object *ob, EEVEE_LampsInfo *linfo, EEVEE
 		mul_v2_v2fl(shadow_origin, center, linfo->shadow_size / (2.0f * sh_data->radius[c]));
 
 		/* Find the nearest texel. */
-		shadow_texco[0] = round(shadow_origin[0]);
-		shadow_texco[1] = round(shadow_origin[1]);
+		shadow_texco[0] = roundf(shadow_origin[0]);
+		shadow_texco[1] = roundf(shadow_origin[1]);
 
 		/* Compute offset. */
 		sub_v2_v2(shadow_texco, shadow_origin);



More information about the Bf-blender-cvs mailing list