[Bf-blender-cvs] [b8331b79e63] blender2.8: Eevee: Implement jittered soft shadowmap

Clément Foucault noreply at git.blender.org
Sun Oct 28 21:41:03 CET 2018


Commit: b8331b79e63cfd80b5a18460e3988fe17fb01fb8
Author: Clément Foucault
Date:   Sun Oct 28 21:41:40 2018 +0100
Branches: blender2.8
https://developer.blender.org/rBb8331b79e63cfd80b5a18460e3988fe17fb01fb8

Eevee: Implement jittered soft shadowmap

This new option is located in the shadows options in the render settings.
This approach is simple and just randomize the shadow map position (not
the lamp itself) and just let the temporal supersampling do the average of
all the shadowing. The downside is that is needs quite a large number of
samples to give smooth results and individual sample position can remain
visible.

Enabling this option will make the viewport refresh all shadow maps every
redraw so it has a serious performance impact.

This approach is not physicaly based at all and will not match cycles.

----

The sampling for point lamps (spheres) is not

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

M	release/scripts/startup/bl_ui/properties_render.py
M	source/blender/draw/engines/eevee/eevee_engine.c
M	source/blender/draw/engines/eevee/eevee_lightcache.c
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
M	source/blender/draw/engines/eevee/eevee_render.c
M	source/blender/makesdna/DNA_scene_types.h
M	source/blender/makesrna/intern/rna_scene.c

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

diff --git a/release/scripts/startup/bl_ui/properties_render.py b/release/scripts/startup/bl_ui/properties_render.py
index fbc19a4c83e..d64570b07ca 100644
--- a/release/scripts/startup/bl_ui/properties_render.py
+++ b/release/scripts/startup/bl_ui/properties_render.py
@@ -748,6 +748,7 @@ class RENDER_PT_eevee_shadows(RenderButtonsPanel, Panel):
         col.prop(props, "shadow_cube_size", text="Cube Size")
         col.prop(props, "shadow_cascade_size", text="Cascade Size")
         col.prop(props, "use_shadow_high_bitdepth")
+        col.prop(props, "use_soft_shadows")
 
 
 class RENDER_PT_eevee_sampling(RenderButtonsPanel, Panel):
diff --git a/source/blender/draw/engines/eevee/eevee_engine.c b/source/blender/draw/engines/eevee/eevee_engine.c
index fdd908dbc44..1d173e6d3fc 100644
--- a/source/blender/draw/engines/eevee/eevee_engine.c
+++ b/source/blender/draw/engines/eevee/eevee_engine.c
@@ -168,7 +168,7 @@ static void eevee_cache_finish(void *vedata)
 	EEVEE_ViewLayerData *sldata = EEVEE_view_layer_data_ensure();
 
 	EEVEE_materials_cache_finish(vedata);
-	EEVEE_lights_cache_finish(sldata);
+	EEVEE_lights_cache_finish(sldata, vedata);
 	EEVEE_lightprobes_cache_finish(sldata, vedata);
 }
 
@@ -249,7 +249,7 @@ static void eevee_draw_background(void *vedata)
 
 		/* Refresh shadows */
 		DRW_stats_group_start("Shadows");
-		EEVEE_draw_shadows(sldata, psl);
+		EEVEE_draw_shadows(sldata, vedata);
 		DRW_stats_group_end();
 
 		GPU_framebuffer_bind(fbl->main_fb);
diff --git a/source/blender/draw/engines/eevee/eevee_lightcache.c b/source/blender/draw/engines/eevee/eevee_lightcache.c
index 425749b0b52..e0616ae9dfe 100644
--- a/source/blender/draw/engines/eevee/eevee_lightcache.c
+++ b/source/blender/draw/engines/eevee/eevee_lightcache.c
@@ -709,7 +709,7 @@ static void eevee_lightbake_cache_create(EEVEE_Data *vedata, EEVEE_LightBake *lb
 	DRW_render_object_iter(vedata, NULL, lbake->depsgraph, EEVEE_render_cache);
 
 	EEVEE_materials_cache_finish(vedata);
-	EEVEE_lights_cache_finish(sldata);
+	EEVEE_lights_cache_finish(sldata, vedata);
 	EEVEE_lightprobes_cache_finish(sldata, vedata);
 
 	txl->color = NULL;
diff --git a/source/blender/draw/engines/eevee/eevee_lightprobes.c b/source/blender/draw/engines/eevee/eevee_lightprobes.c
index 3d236a5ddd9..d1e798098bb 100644
--- a/source/blender/draw/engines/eevee/eevee_lightprobes.c
+++ b/source/blender/draw/engines/eevee/eevee_lightprobes.c
@@ -972,7 +972,7 @@ static void lightbake_render_scene_face(int face, EEVEE_BakeRenderData *user_dat
 	struct GPUFrameBuffer **face_fb = user_data->face_fb;
 
 	/* Be sure that cascaded shadow maps are updated. */
-	EEVEE_draw_shadows(sldata, psl);
+	EEVEE_draw_shadows(sldata, user_data->vedata);
 
 	GPU_framebuffer_bind(face_fb[face]);
 	GPU_framebuffer_clear_depth(face_fb[face], 1.0f);
@@ -1028,7 +1028,7 @@ static void lightbake_render_scene_reflected(int layer, EEVEE_BakeRenderData *us
 	DRW_stats_group_start("Planar Reflection");
 
 	/* Be sure that cascaded shadow maps are updated. */
-	EEVEE_draw_shadows(sldata, psl);
+	EEVEE_draw_shadows(sldata, vedata);
 	/* 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();
diff --git a/source/blender/draw/engines/eevee/eevee_lights.c b/source/blender/draw/engines/eevee/eevee_lights.c
index 7319572d7eb..44bc4653037 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_rand.h"
 #include "BLI_rect.h"
 
 #include "BKE_object.h"
@@ -38,6 +39,7 @@
 #define SHADOW_CASTER_ALLOC_CHUNK 16
 
 // #define DEBUG_CSM
+// #define DEBUG_SHADOW_DISTRIBUTION
 
 static struct {
 	struct GPUShader *shadow_sh;
@@ -138,6 +140,7 @@ void EEVEE_lights_init(EEVEE_ViewLayerData *sldata)
 	int sh_cube_size = scene_eval->eevee.shadow_cube_size;
 	int sh_cascade_size = scene_eval->eevee.shadow_cascade_size;
 	const bool sh_high_bitdepth = (scene_eval->eevee.flag & SCE_EEVEE_SHADOW_HIGH_BITDEPTH) != 0;
+	sldata->lamps->soft_shadows = (scene_eval->eevee.flag & SCE_EEVEE_SHADOW_SOFT) != 0;
 
 	EEVEE_LampsInfo *linfo = sldata->lamps;
 	if ((linfo->shadow_cube_size != sh_cube_size) ||
@@ -518,7 +521,7 @@ void EEVEE_lights_cache_shcaster_object_add(EEVEE_ViewLayerData *sldata, Object
 	oedata->need_update = false;
 }
 
-void EEVEE_lights_cache_finish(EEVEE_ViewLayerData *sldata)
+void EEVEE_lights_cache_finish(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
 {
 	EEVEE_LampsInfo *linfo = sldata->lamps;
 	GPUTextureFormat shadow_pool_format = GPU_R32F;
@@ -587,7 +590,7 @@ void EEVEE_lights_cache_finish(EEVEE_ViewLayerData *sldata)
 	});
 
 	/* Update Lamps UBOs. */
-	EEVEE_lights_update(sldata);
+	EEVEE_lights_update(sldata, vedata);
 }
 
 /* Update buffer with lamp data */
@@ -670,7 +673,108 @@ static void eevee_light_setup(Object *ob, EEVEE_Light *evli)
 	evli->shadowid = -1.0f;
 }
 
-static void eevee_shadow_cube_setup(Object *ob, EEVEE_LampsInfo *linfo, EEVEE_LampEngineData *led)
+/**
+ * Special ball distribution:
+ * Point are distributed in a way that when they are orthogonaly
+ * projected into any plane, the resulting distribution is (close to)
+ * a uniform disc distribution.
+ **/
+static void sample_ball(int sample_ofs, float radius, float rsample[3])
+{
+	double ht_point[3];
+	double ht_offset[3] = {0.0, 0.0, 0.0};
+	uint ht_primes[3] = {2, 3, 7};
+
+	BLI_halton_3D(ht_primes, ht_offset, sample_ofs, ht_point);
+
+	float omega = ht_point[1] * 2.0f * M_PI;
+
+	rsample[2] = ht_point[0] * 2.0f - 1.0f; /* cos theta */
+
+	float r = sqrtf(fmaxf(0.0f, 1.0f - rsample[2]*rsample[2])); /* sin theta */
+
+	rsample[0] = r * cosf(omega);
+	rsample[1] = r * sinf(omega);
+
+	radius *= sqrt(sqrt(ht_point[2]));
+	mul_v3_fl(rsample, radius);
+}
+
+static void sample_rectangle(
+        int sample_ofs, float x_axis[3], float y_axis[3], float size_x, float size_y,
+        float rsample[3])
+{
+	double ht_point[2];
+	double ht_offset[2] = {0.0, 0.0};
+	uint ht_primes[2] = {2, 3};
+
+	BLI_halton_2D(ht_primes, ht_offset, sample_ofs, ht_point);
+
+	/* Change ditribution center to be 0,0 */
+	ht_point[0] = (ht_point[0] > 0.5f) ? ht_point[0] - 1.0f : ht_point[0];
+	ht_point[1] = (ht_point[1] > 0.5f) ? ht_point[1] - 1.0f : ht_point[1];
+
+	zero_v3(rsample);
+	madd_v3_v3fl(rsample, x_axis, (ht_point[0] * 2.0f) * size_x);
+	madd_v3_v3fl(rsample, y_axis, (ht_point[1] * 2.0f) * size_y);
+}
+
+static void sample_ellipse(
+        int sample_ofs, float x_axis[3], float y_axis[3], float size_x, float size_y,
+        float rsample[3])
+{
+	double ht_point[2];
+	double ht_offset[2] = {0.0, 0.0};
+	uint ht_primes[2] = {2, 3};
+
+	BLI_halton_2D(ht_primes, ht_offset, sample_ofs, ht_point);
+
+	/* Uniform disc sampling. */
+	float omega = ht_point[1] * 2.0f * M_PI;
+	float r = sqrtf(ht_point[0]);
+	ht_point[0] = r * cosf(omega) * size_x;
+	ht_point[1] = r * sinf(omega) * size_y;
+
+	zero_v3(rsample);
+	madd_v3_v3fl(rsample, x_axis, ht_point[0]);
+	madd_v3_v3fl(rsample, y_axis, ht_point[1]);
+}
+
+
+static void shadow_cube_random_position_set(
+		EEVEE_Light *evli, Lamp *la,
+        int sample_ofs,
+        float ws_sample_pos[3])
+{
+	float jitter[3];
+
+#ifndef DEBUG_SHADOW_DISTRIBUTION
+	int i = sample_ofs;
+#else
+	for (int i = 1; i <= sample_ofs; ++i) {
+#endif
+		switch (la->type) {
+			case LA_AREA:
+				if (ELEM(la->area_shape, LA_AREA_RECT, LA_AREA_SQUARE)) {
+					sample_rectangle(i, evli->rightvec, evli->upvec, evli->sizex, evli->sizey, jitter);
+				}
+				else {
+					sample_ellipse(i, evli->rightvec, evli->upvec, evli->sizex, evli->sizey, jitter);
+				}
+				break;
+			default:
+				sample_ball(i, evli->radius, jitter);
+		}
+#ifdef DEBUG_SHADOW_DISTRIBUTION
+		float p[3];
+		add_v3_v3v3(p, jitter, ws_sample_pos);
+		DRW_debug_sphere(p, 0.01f, (float[4]){1.0f, (sample_ofs == i) ? 1.0f : 0.0f, 0.0f, 1.0f});
+	}
+#endif
+	add_v3_v3(ws_sample_pos, jitter);
+}
+
+static void eevee_shadow_cube_setup(Object *ob, EEVEE_LampsInfo *linfo, EEVEE_LampEngineData *led, int sample_ofs)
 {
 	EEVEE_ShadowCubeData *sh_data = &led->data.scd;
 	EEVEE_Light *evli = linfo->light_data + sh_data->light_id;
@@ -678,11 +782,10 @@ static void eevee_shadow_cube_setup(Object *ob, EEVEE_LampsInfo *linfo, EEVEE_La
 	EEVEE_ShadowCube *cube_data = linfo->shadow_cube_data + sh_data->cube_id;
 	Lamp *la = (Lamp *)ob->data;
 
-	int sh_nbr = 1; /* TODO: MSM */
+	copy_v3_v3(cube_data->position, ob->obmat[3]);
 
-	for (int i = 0; i < sh_nbr; ++i) {
-		/* TODO : choose MSM sample point here. */
-		copy_v3_v3(cube_data->position, ob->obmat[3]);
+	if (linfo->soft_shadows) {
+		shadow_cube_random_position_set(evli, la, sample_ofs, cube_data->position);
 	}
 
 	ubo_data->bias = 0.05f * la->bias;
@@ -693,7 +796,6 @@ static void eevee_shadow_cube_setup(Object *ob, EEVEE_LampsInfo *linfo, EEVEE_La
 	evli->shadowid = (float)(sh_data->shadow_id);
 	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->shadow_blur = la->soft * 0.02f; /* Used by translucence shadowmap blur */
 
 	ubo_data->contact_dist = (la->mode & LA_SHAD_CONTACT) ? la->contact_dist : 0.0f;
@@ -702,6 +804,27 @@ static void eevee_shadow_cube_setup(Object *ob, EEVEE_LampsInfo *linfo, EEVEE_La
 	ubo_data->contact_thickness = la->contact_thickness;
 }
 
+static void shadow_cascade_random_matrix_set(float mat[4][4], float radius, int sample_ofs)
+{
+	float jitter[3];
+
+#ifndef DEBUG_SHADOW_DISTRIBUTION
+	int i = sample_ofs;
+#else
+	for (int i = 1; i <= sample_ofs; ++i) {
+#endif
+		sample_ellipse(i, mat[0], mat[1], radius, radius, jitter);
+#ifdef DEBUG_SHADOW_DISTRIBUTION
+		float p[3];
+		add_v3_v3v3(p, jitter, mat[2]);
+		DRW_debug_sphere(p, 0.01f, (float[4]){1.0f, (sample_ofs == i) ? 1.0f : 0.0f, 0.0f, 1.0f});
+	}
+#endif
+
+	add_v3_v3(mat[2], jitter);
+	orthogonalize_m4(mat, 2);
+}
+
 #define LERP(t, a, b) ((a) + (t) * ((b) - (a)))
 
 static double round_to_digits(double value, int digits)
@@ -752,7 +875,7 @@ static void frustum_min_bounding_sphere(const float corners[8][3], float r_cente
 
 static

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list