[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