[Bf-blender-cvs] [8b7a83a868c] blender2.8: Eevee: Refactor Shadow System

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


Commit: 8b7a83a868c03f3d721eb83498923673c2addb27
Author: Clément Foucault
Date:   Fri Sep 1 15:59:01 2017 +0200
Branches: blender2.8
https://developer.blender.org/rB8b7a83a868c03f3d721eb83498923673c2addb27

Eevee: Refactor Shadow System

- Use only one 2d texture array to store all shadowmaps.
- Allow to change shadow maps resolution.
- Do not output radial distance when rendering shadowmaps. This will allow fast rendering of shadowmaps when we will drop the use of geometry shaders.

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

M	source/blender/draw/CMakeLists.txt
M	source/blender/draw/engines/eevee/eevee_data.c
M	source/blender/draw/engines/eevee/eevee_effects.c
M	source/blender/draw/engines/eevee/eevee_engine.c
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/prepass_frag.glsl
M	source/blender/draw/engines/eevee/shaders/shadow_frag.glsl
M	source/blender/draw/engines/eevee/shaders/shadow_geom.glsl
M	source/blender/draw/engines/eevee/shaders/shadow_store_frag.glsl
D	source/blender/draw/engines/eevee/shaders/shadow_store_geom.glsl
D	source/blender/draw/engines/eevee/shaders/shadow_store_vert.glsl
M	source/blender/draw/intern/draw_manager.c

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

diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt
index 63f466d3792..c9f0dedfbdd 100644
--- a/source/blender/draw/CMakeLists.txt
+++ b/source/blender/draw/CMakeLists.txt
@@ -154,8 +154,6 @@ data_to_c_simple(engines/eevee/shaders/shadow_frag.glsl SRC)
 data_to_c_simple(engines/eevee/shaders/shadow_geom.glsl SRC)
 data_to_c_simple(engines/eevee/shaders/shadow_vert.glsl SRC)
 data_to_c_simple(engines/eevee/shaders/shadow_store_frag.glsl SRC)
-data_to_c_simple(engines/eevee/shaders/shadow_store_geom.glsl SRC)
-data_to_c_simple(engines/eevee/shaders/shadow_store_vert.glsl SRC)
 data_to_c_simple(engines/eevee/shaders/bsdf_lut_frag.glsl SRC)
 data_to_c_simple(engines/eevee/shaders/btdf_lut_frag.glsl SRC)
 data_to_c_simple(engines/eevee/shaders/bsdf_direct_lib.glsl SRC)
diff --git a/source/blender/draw/engines/eevee/eevee_data.c b/source/blender/draw/engines/eevee/eevee_data.c
index 36d91c0cc28..28c049ae53e 100644
--- a/source/blender/draw/engines/eevee/eevee_data.c
+++ b/source/blender/draw/engines/eevee/eevee_data.c
@@ -39,15 +39,11 @@ static void eevee_scene_layer_data_free(void *storage)
 	DRW_UBO_FREE_SAFE(sldata->light_ubo);
 	DRW_UBO_FREE_SAFE(sldata->shadow_ubo);
 	DRW_UBO_FREE_SAFE(sldata->shadow_render_ubo);
-	DRW_FRAMEBUFFER_FREE_SAFE(sldata->shadow_cube_target_fb);
-	DRW_FRAMEBUFFER_FREE_SAFE(sldata->shadow_cube_fb);
-	DRW_FRAMEBUFFER_FREE_SAFE(sldata->shadow_map_fb);
-	DRW_FRAMEBUFFER_FREE_SAFE(sldata->shadow_cascade_fb);
-	DRW_TEXTURE_FREE_SAFE(sldata->shadow_depth_cube_target);
-	DRW_TEXTURE_FREE_SAFE(sldata->shadow_color_cube_target);
-	DRW_TEXTURE_FREE_SAFE(sldata->shadow_depth_cube_pool);
-	DRW_TEXTURE_FREE_SAFE(sldata->shadow_depth_map_pool);
-	DRW_TEXTURE_FREE_SAFE(sldata->shadow_depth_cascade_pool);
+	DRW_FRAMEBUFFER_FREE_SAFE(sldata->shadow_target_fb);
+	DRW_FRAMEBUFFER_FREE_SAFE(sldata->shadow_store_fb);
+	DRW_TEXTURE_FREE_SAFE(sldata->shadow_cube_target);
+	DRW_TEXTURE_FREE_SAFE(sldata->shadow_cascade_target);
+	DRW_TEXTURE_FREE_SAFE(sldata->shadow_pool);
 	BLI_freelistN(&sldata->shadow_casters);
 
 	/* Probes */
diff --git a/source/blender/draw/engines/eevee/eevee_effects.c b/source/blender/draw/engines/eevee/eevee_effects.c
index ace350cada1..cacfd5a5957 100644
--- a/source/blender/draw/engines/eevee/eevee_effects.c
+++ b/source/blender/draw/engines/eevee/eevee_effects.c
@@ -811,7 +811,7 @@ void EEVEE_effects_cache_init(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata)
 
 		if (grp != NULL) {
 			DRW_shgroup_uniform_buffer(grp, "depthFull", &e_data.depth_src);
-			DRW_shgroup_uniform_buffer(grp, "shadowCubes", &sldata->shadow_depth_cube_pool);
+			DRW_shgroup_uniform_buffer(grp, "shadowTexture", &sldata->shadow_pool);
 			DRW_shgroup_uniform_buffer(grp, "irradianceGrid", &sldata->irradiance_pool);
 			DRW_shgroup_uniform_block(grp, "light_block", sldata->light_ubo);
 			DRW_shgroup_uniform_block(grp, "grid_block", sldata->grid_ubo);
diff --git a/source/blender/draw/engines/eevee/eevee_engine.c b/source/blender/draw/engines/eevee/eevee_engine.c
index 9ab551ad949..735c3a77c5d 100644
--- a/source/blender/draw/engines/eevee/eevee_engine.c
+++ b/source/blender/draw/engines/eevee/eevee_engine.c
@@ -309,6 +309,9 @@ static void EEVEE_scene_layer_settings_create(RenderEngine *UNUSED(engine), IDPr
 	BKE_collection_engine_property_add_bool(props, "motion_blur_enable", false);
 	BKE_collection_engine_property_add_int(props, "motion_blur_samples", 8);
 	BKE_collection_engine_property_add_float(props, "motion_blur_shutter", 1.0f);
+
+	BKE_collection_engine_property_add_int(props, "shadow_method", SHADOW_ESM);
+	BKE_collection_engine_property_add_int(props, "shadow_size", 512);
 }
 
 static const DrawEngineDataSize EEVEE_data_size = DRW_VIEWPORT_DATA_SIZE(EEVEE_Data);
diff --git a/source/blender/draw/engines/eevee/eevee_lights.c b/source/blender/draw/engines/eevee/eevee_lights.c
index 8f5c633c24a..6af1ad63fd7 100644
--- a/source/blender/draw/engines/eevee/eevee_lights.c
+++ b/source/blender/draw/engines/eevee/eevee_lights.c
@@ -42,11 +42,6 @@ typedef struct EEVEE_ShadowCubeData {
 	float viewprojmat[6][4][4];
 } EEVEE_ShadowCubeData;
 
-typedef struct EEVEE_ShadowMapData {
-	short light_id, shadow_id;
-	float viewprojmat[4][4]; /* World->Lamp->NDC : used for rendering the shadow map. */
-} EEVEE_ShadowMapData;
-
 typedef struct EEVEE_ShadowCascadeData {
 	short light_id, shadow_id;
 	float viewprojmat[MAX_CASCADE_NUM][4][4]; /* World->Lamp->NDC : used for rendering the shadow map. */
@@ -60,14 +55,13 @@ typedef struct ShadowCaster {
 
 static struct {
 	struct GPUShader *shadow_sh;
-	struct GPUShader *shadow_store_sh;
+	struct GPUShader *shadow_store_cube_sh;
+	struct GPUShader *shadow_store_cascade_sh;
 } e_data = {NULL}; /* Engine data */
 
 extern char datatoc_shadow_vert_glsl[];
 extern char datatoc_shadow_geom_glsl[];
 extern char datatoc_shadow_frag_glsl[];
-extern char datatoc_shadow_store_vert_glsl[];
-extern char datatoc_shadow_store_geom_glsl[];
 extern char datatoc_shadow_store_frag_glsl[];
 
 /* *********** FUNCTIONS *********** */
@@ -75,15 +69,18 @@ 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 +
-	                                     sizeof(EEVEE_ShadowMap) * MAX_SHADOW_MAP +
 	                                     sizeof(EEVEE_ShadowCascade) * MAX_SHADOW_CASCADE;
 
+	const DRWContextState *draw_ctx = DRW_context_state_get();
+	SceneLayer *scene_layer = draw_ctx->scene_layer;
+	IDProperty *props = BKE_scene_layer_engine_evaluated_get(scene_layer, COLLECTION_MODE_NONE, RE_engine_id_BLENDER_EEVEE);
+
 	if (!e_data.shadow_sh) {
 		e_data.shadow_sh = DRW_shader_create(
 		        datatoc_shadow_vert_glsl, datatoc_shadow_geom_glsl, datatoc_shadow_frag_glsl, NULL);
 
-		e_data.shadow_store_sh = DRW_shader_create(
-		        datatoc_shadow_store_vert_glsl, datatoc_shadow_store_geom_glsl, datatoc_shadow_store_frag_glsl, NULL);
+		e_data.shadow_store_cube_sh = DRW_shader_create_fullscreen(datatoc_shadow_store_frag_glsl, NULL);
+		e_data.shadow_store_cascade_sh = DRW_shader_create_fullscreen(datatoc_shadow_store_frag_glsl, "#define CSM");
 	}
 
 	if (!sldata->lamps) {
@@ -92,23 +89,58 @@ void EEVEE_lights_init(EEVEE_SceneLayerData *sldata)
 		sldata->shadow_ubo         = DRW_uniformbuffer_create(shadow_ubo_size, NULL);
 		sldata->shadow_render_ubo  = DRW_uniformbuffer_create(sizeof(EEVEE_ShadowRender), NULL);
 	}
+
+	int sh_method = BKE_collection_engine_property_value_get_int(props, "shadow_method");
+	int sh_size = BKE_collection_engine_property_value_get_int(props, "shadow_size");
+	UNUSED_VARS(sh_method);
+
+	EEVEE_LampsInfo *linfo = sldata->lamps;
+	if (linfo->shadow_size != sh_size) {
+		BLI_assert((sh_size > 0) && (sh_size <= 8192));
+		DRW_TEXTURE_FREE_SAFE(sldata->shadow_pool);
+		DRW_TEXTURE_FREE_SAFE(sldata->shadow_cascade_target);
+
+		linfo->shadow_size = sh_size;
+		linfo->shadow_render_data.stored_texel_size = 1.0 / (float)linfo->shadow_size;
+
+		/* Compute adequate size for the cubemap render target.
+		 * The 3.0f factor is here to make sure there is no under sampling between
+		 * the octahedron mapping and the cubemap. */
+		int new_cube_target_size = (int)ceil(sqrt((float)(sh_size * sh_size) / 6.0f) * 3.0f);
+
+		CLAMP(new_cube_target_size, 1, 4096);
+
+		if (linfo->shadow_cube_target_size != new_cube_target_size) {
+			linfo->shadow_cube_target_size = new_cube_target_size;
+			DRW_TEXTURE_FREE_SAFE(sldata->shadow_cube_target);
+			linfo->shadow_render_data.cube_texel_size = 1.0 / (float)linfo->shadow_cube_target_size;
+		}
+	}
 }
 
 void EEVEE_lights_cache_init(EEVEE_SceneLayerData *sldata, EEVEE_PassList *psl)
 {
 	EEVEE_LampsInfo *linfo = sldata->lamps;
 
-	linfo->num_light = linfo->num_cube = linfo->num_map = linfo->num_cascade = 0;
+	linfo->num_light = linfo->num_cube = linfo->num_cascade = linfo->num_shadow = 0;
 	memset(linfo->light_ref, 0, sizeof(linfo->light_ref));
 	memset(linfo->shadow_cube_ref, 0, sizeof(linfo->shadow_cube_ref));
-	memset(linfo->shadow_map_ref, 0, sizeof(linfo->shadow_map_ref));
 	memset(linfo->shadow_cascade_ref, 0, sizeof(linfo->shadow_cascade_ref));
 
 	{
 		psl->shadow_cube_store_pass = DRW_pass_create("Shadow Storage Pass", DRW_STATE_WRITE_COLOR);
 
-		DRWShadingGroup *grp = DRW_shgroup_create(e_data.shadow_store_sh, psl->shadow_cube_store_pass);
-		DRW_shgroup_uniform_buffer(grp, "shadowCube", &sldata->shadow_color_cube_target);
+		DRWShadingGroup *grp = DRW_shgroup_create(e_data.shadow_store_cube_sh, 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_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL);
+	}
+
+	{
+		psl->shadow_cascade_store_pass = DRW_pass_create("Shadow Cascade Storage Pass", DRW_STATE_WRITE_COLOR);
+
+		DRWShadingGroup *grp = DRW_shgroup_create(e_data.shadow_store_cascade_sh, 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_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL);
 	}
@@ -118,7 +150,7 @@ void EEVEE_lights_cache_init(EEVEE_SceneLayerData *sldata, EEVEE_PassList *psl)
 	}
 
 	{
-		psl->shadow_cascade_pass = DRW_pass_create("Shadow Cascade Pass", DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS);
+		psl->shadow_cascade_pass = DRW_pass_create("Shadow Cascade Pass", DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS);
 	}
 
 	/* Reset shadow casters list */
@@ -147,19 +179,19 @@ void EEVEE_lights_cache_add(EEVEE_SceneLayerData *sldata, Object *ob)
 #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) {
-#if 0 /* TODO filter cascaded shadow map */
 				led->storage = MEM_mallocN(sizeof(EEVEE_ShadowCascadeData), "EEVEE_ShadowCascadeData");
-				((EEVEE_ShadowCascadeData *)led->storage)->sha

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list