[Bf-blender-cvs] [32e96448b9d] blender2.8: Eevee: Add Variance Shadow Mapping

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


Commit: 32e96448b9d08b7975f6afd73b2569a6b81a125e
Author: Clément Foucault
Date:   Fri Sep 1 18:39:39 2017 +0200
Branches: blender2.8
https://developer.blender.org/rB32e96448b9d08b7975f6afd73b2569a6b81a125e

Eevee: Add Variance Shadow Mapping

This is an alternative to ESM. It does not suffer the same bleeding artifacts.

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

M	release/scripts/startup/bl_ui/properties_data_lamp.py
M	release/scripts/startup/bl_ui/properties_render_layer.py
M	source/blender/draw/engines/eevee/eevee_effects.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/shadow_store_frag.glsl
M	source/blender/makesrna/intern/rna_scene.c

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

diff --git a/release/scripts/startup/bl_ui/properties_data_lamp.py b/release/scripts/startup/bl_ui/properties_data_lamp.py
index c4cd433f143..6c4d7e9d1c4 100644
--- a/release/scripts/startup/bl_ui/properties_data_lamp.py
+++ b/release/scripts/startup/bl_ui/properties_data_lamp.py
@@ -384,6 +384,7 @@ class DATA_PT_EEVEE_shadow(DataButtonsPanel, Panel):
             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/release/scripts/startup/bl_ui/properties_render_layer.py b/release/scripts/startup/bl_ui/properties_render_layer.py
index 6c4ab256594..250a4ea61a3 100644
--- a/release/scripts/startup/bl_ui/properties_render_layer.py
+++ b/release/scripts/startup/bl_ui/properties_render_layer.py
@@ -321,6 +321,7 @@ classes = (
     RENDERLAYER_PT_eevee_postprocess_settings,
     RENDERLAYER_PT_eevee_screen_space_reflections,
     RENDERLAYER_PT_eevee_volumetric,
+    RENDERLAYER_PT_eevee_shadows,
 )
 
 if __name__ == "__main__":  # only for live edit.
diff --git a/source/blender/draw/engines/eevee/eevee_effects.c b/source/blender/draw/engines/eevee/eevee_effects.c
index cacfd5a5957..73c7b4e96b3 100644
--- a/source/blender/draw/engines/eevee/eevee_effects.c
+++ b/source/blender/draw/engines/eevee/eevee_effects.c
@@ -804,7 +804,7 @@ void EEVEE_effects_cache_init(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata)
 
 		struct GPUMaterial *mat = EEVEE_material_world_volume_get(
 		        scene, wo, volumetrics->use_lights, volumetrics->use_volume_shadows,
-		        false, volumetrics->use_colored_transmit);
+		        false, volumetrics->use_colored_transmit, sldata->lamps->shadow_method);
 
 		psl->volumetric_integrate_ps = DRW_pass_create("Volumetric Integration", DRW_STATE_WRITE_COLOR);
 		DRWShadingGroup *grp = DRW_shgroup_material_create(mat, psl->volumetric_integrate_ps);
diff --git a/source/blender/draw/engines/eevee/eevee_lights.c b/source/blender/draw/engines/eevee/eevee_lights.c
index 6af1ad63fd7..20d46619787 100644
--- a/source/blender/draw/engines/eevee/eevee_lights.c
+++ b/source/blender/draw/engines/eevee/eevee_lights.c
@@ -55,8 +55,8 @@ typedef struct ShadowCaster {
 
 static struct {
 	struct GPUShader *shadow_sh;
-	struct GPUShader *shadow_store_cube_sh;
-	struct GPUShader *shadow_store_cascade_sh;
+	struct GPUShader *shadow_store_cube_sh[SHADOW_METHOD_MAX];
+	struct GPUShader *shadow_store_cascade_sh[SHADOW_METHOD_MAX];
 } e_data = {NULL}; /* Engine data */
 
 extern char datatoc_shadow_vert_glsl[];
@@ -79,8 +79,13 @@ void EEVEE_lights_init(EEVEE_SceneLayerData *sldata)
 		e_data.shadow_sh = DRW_shader_create(
 		        datatoc_shadow_vert_glsl, datatoc_shadow_geom_glsl, datatoc_shadow_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");
+		e_data.shadow_store_cube_sh[SHADOW_ESM] = DRW_shader_create_fullscreen(datatoc_shadow_store_frag_glsl, "#define ESM\n");
+		e_data.shadow_store_cascade_sh[SHADOW_ESM] = DRW_shader_create_fullscreen(datatoc_shadow_store_frag_glsl, "#define ESM\n"
+		                                                                                                          "#define CSM\n");
+
+		e_data.shadow_store_cube_sh[SHADOW_VSM] = DRW_shader_create_fullscreen(datatoc_shadow_store_frag_glsl, "#define VSM\n");
+		e_data.shadow_store_cascade_sh[SHADOW_VSM] = DRW_shader_create_fullscreen(datatoc_shadow_store_frag_glsl, "#define VSM\n"
+		                                                                                                          "#define CSM\n");
 	}
 
 	if (!sldata->lamps) {
@@ -92,14 +97,14 @@ void EEVEE_lights_init(EEVEE_SceneLayerData *sldata)
 
 	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) {
+	if ((linfo->shadow_size != sh_size) || (linfo->shadow_method != sh_method)) {
 		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_method = sh_method;
 		linfo->shadow_size = sh_size;
 		linfo->shadow_render_data.stored_texel_size = 1.0 / (float)linfo->shadow_size;
 
@@ -130,7 +135,7 @@ void EEVEE_lights_cache_init(EEVEE_SceneLayerData *sldata, EEVEE_PassList *psl)
 	{
 		psl->shadow_cube_store_pass = DRW_pass_create("Shadow Storage Pass", DRW_STATE_WRITE_COLOR);
 
-		DRWShadingGroup *grp = DRW_shgroup_create(e_data.shadow_store_cube_sh, psl->shadow_cube_store_pass);
+		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_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL);
@@ -139,7 +144,7 @@ void EEVEE_lights_cache_init(EEVEE_SceneLayerData *sldata, EEVEE_PassList *psl)
 	{
 		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);
+		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_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL);
@@ -273,8 +278,13 @@ void EEVEE_lights_cache_finish(EEVEE_SceneLayerData *sldata)
 		linfo->update_flag |= LIGHT_UPDATE_SHADOW_CUBE;
 	}
 
-	/* TODO Variance Shadow Map */
-	shadow_pool_format = DRW_TEX_R_32;
+	switch (linfo->shadow_method) {
+		case SHADOW_ESM: shadow_pool_format = DRW_TEX_R_32; break;
+		case SHADOW_VSM: shadow_pool_format = DRW_TEX_RG_32; break;
+		default:
+			BLI_assert(!"Incorrect Shadow Method");
+			break;
+	}
 
 	if (!sldata->shadow_cube_target) {
 		/* TODO render everything on the same 2d render target using clip planes and no Geom Shader. */
@@ -412,7 +422,7 @@ static void eevee_shadow_cube_setup(Object *ob, EEVEE_LampsInfo *linfo, EEVEE_La
 	evsh->bias = 0.05f * la->bias;
 	evsh->near = la->clipsta;
 	evsh->far = la->clipend;
-	evsh->exp = la->bleedexp;
+	evsh->exp = (linfo->shadow_method == SHADOW_VSM) ? la->bleedbias : la->bleedexp;
 
 	evli->shadowid = (float)(evsmp->shadow_id);
 }
@@ -797,6 +807,8 @@ void EEVEE_draw_shadows(EEVEE_SceneLayerData *sldata, EEVEE_PassList *psl)
 void EEVEE_lights_free(void)
 {
 	DRW_SHADER_FREE_SAFE(e_data.shadow_sh);
-	DRW_SHADER_FREE_SAFE(e_data.shadow_store_cube_sh);
-	DRW_SHADER_FREE_SAFE(e_data.shadow_store_cascade_sh);
+	for (int i = 0; i < SHADOW_METHOD_MAX; ++i) {
+		DRW_SHADER_FREE_SAFE(e_data.shadow_store_cube_sh[i]);
+		DRW_SHADER_FREE_SAFE(e_data.shadow_store_cascade_sh[i]);
+	}
 }
\ No newline at end of file
diff --git a/source/blender/draw/engines/eevee/eevee_materials.c b/source/blender/draw/engines/eevee/eevee_materials.c
index e1852e44722..296fc7b02a0 100644
--- a/source/blender/draw/engines/eevee/eevee_materials.c
+++ b/source/blender/draw/engines/eevee/eevee_materials.c
@@ -268,6 +268,19 @@ struct GPUTexture *EEVEE_materials_get_util_tex(void)
 	return e_data.util_tex;
 }
 
+static int eevee_material_shadow_option(int shadow_method)
+{
+	switch (shadow_method) {
+		case SHADOW_ESM: return VAR_MAT_ESM;
+		case SHADOW_VSM: return VAR_MAT_VSM;
+		default:
+			BLI_assert(!"Incorrect Shadow Method");
+			break;
+	}
+
+	return 0;
+}
+
 static char *eevee_get_defines(int options)
 {
 	char *str = NULL;
@@ -305,6 +318,12 @@ static char *eevee_get_defines(int options)
 	if ((options & VAR_MAT_REFRACT) != 0) {
 		BLI_dynstr_appendf(ds, "#define USE_REFRACTION\n");
 	}
+	if ((options & VAR_MAT_VSM) != 0) {
+		BLI_dynstr_appendf(ds, "#define SHADOW_VSM\n");
+	}
+	if ((options & VAR_MAT_ESM) != 0) {
+		BLI_dynstr_appendf(ds, "#define SHADOW_ESM\n");
+	}
 
 	str = BLI_dynstr_get_cstring(ds);
 	BLI_dynstr_free(ds);
@@ -601,7 +620,7 @@ struct GPUMaterial *EEVEE_material_world_background_get(struct Scene *scene, Wor
 
 struct GPUMaterial *EEVEE_material_world_volume_get(
         struct Scene *scene, World *wo,
-        bool use_lights, bool use_volume_shadows, bool is_homogeneous, bool use_color_transmit)
+        bool use_lights, bool use_volume_shadows, bool is_homogeneous, bool use_color_transmit, int shadow_method)
 {
 	const void *engine = &DRW_engine_viewport_eevee_type;
 	int options = VAR_WORLD_VOLUME;
@@ -611,6 +630,8 @@ struct GPUMaterial *EEVEE_material_world_volume_get(
 	if (use_volume_shadows) options |= VAR_VOLUME_SHADOW;
 	if (use_color_transmit) options |= VAR_VOLUME_COLOR;
 
+	options |= eevee_material_shadow_option(shadow_method);
+
 	GPUMaterial *mat = GPU_material_from_nodetree_find(&wo->gpumaterial, engine, options);
 	if (mat != NULL) {
 		return mat;
@@ -630,7 +651,7 @@ struct GPUMaterial *EEVEE_material_world_volume_get(
 
 struct GPUMaterial *EEVEE_material_mesh_get(
         struct Scene *scene, Material *ma,
-        bool use_blend, bool use_multiply, bool use_refract)
+        bool use_blend, bool use_multiply, bool use_refract, int shadow_method)
 {
 	const void *engine = &DRW_engine_viewport_eevee_type;
 	int options = VAR_MAT_MESH;
@@ -639,6 +660,8 @@ struct GPUMaterial *EEVEE_material_mesh_get(
 	if (use_multiply) options |= VAR_MAT_MULT;
 	if (use_refract) options |= VAR_MAT_REFRACT;
 
+	options |= eevee_material_shadow_option(shadow_method);
+
 	GPUMaterial *mat = GPU_material_from_nodetree_find(&ma->gpumaterial, engine, options);
 	if (mat) {
 		return mat;
@@ -700,11 +723,13 @@ struct GPUMaterial *EEVEE_material_mesh_depth_get(
 }
 
 struct GPUM

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list