Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorClément Foucault <foucault.clem@gmail.com>2017-09-01 16:59:01 +0300
committerClément Foucault <foucault.clem@gmail.com>2017-09-10 04:09:45 +0300
commit8b7a83a868c03f3d721eb83498923673c2addb27 (patch)
treeb51d9a4310e4521cc484b650804fe07e69a9a7f2 /source
parent5b026486e4f2a36bf4c988593ebecb135a2ccf84 (diff)
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.
Diffstat (limited to 'source')
-rw-r--r--source/blender/draw/CMakeLists.txt2
-rw-r--r--source/blender/draw/engines/eevee/eevee_data.c14
-rw-r--r--source/blender/draw/engines/eevee/eevee_effects.c2
-rw-r--r--source/blender/draw/engines/eevee/eevee_engine.c3
-rw-r--r--source/blender/draw/engines/eevee/eevee_lights.c233
-rw-r--r--source/blender/draw/engines/eevee/eevee_materials.c4
-rw-r--r--source/blender/draw/engines/eevee/eevee_private.h49
-rw-r--r--source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl34
-rw-r--r--source/blender/draw/engines/eevee/shaders/lamps_lib.glsl27
-rw-r--r--source/blender/draw/engines/eevee/shaders/prepass_frag.glsl9
-rw-r--r--source/blender/draw/engines/eevee/shaders/shadow_frag.glsl15
-rw-r--r--source/blender/draw/engines/eevee/shaders/shadow_geom.glsl8
-rw-r--r--source/blender/draw/engines/eevee/shaders/shadow_store_frag.glsl158
-rw-r--r--source/blender/draw/engines/eevee/shaders/shadow_store_geom.glsl24
-rw-r--r--source/blender/draw/engines/eevee/shaders/shadow_store_vert.glsl8
-rw-r--r--source/blender/draw/intern/draw_manager.c2
16 files changed, 289 insertions, 303 deletions
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)->shadow_id = linfo->num_cascade;
+ ((EEVEE_ShadowCascadeData *)led->storage)->shadow_id = linfo->num_shadow;
linfo->shadow_cascade_ref[linfo->num_cascade] = ob;
linfo->num_cascade++;
-#endif
+ linfo->num_shadow += MAX_CASCADE_NUM;
}
else if ((la->type == LA_SPOT || la->type == LA_LOCAL || la->type == LA_AREA)
&& linfo->num_cube < MAX_SHADOW_CUBE) {
led->storage = MEM_mallocN(sizeof(EEVEE_ShadowCubeData), "EEVEE_ShadowCubeData");
- ((EEVEE_ShadowCubeData *)led->storage)->shadow_id = linfo->num_cube;
+ ((EEVEE_ShadowCubeData *)led->storage)->shadow_id = linfo->num_shadow;
linfo->shadow_cube_ref[linfo->num_cube] = ob;
linfo->num_cube++;
+ linfo->num_shadow += 1;
}
}
@@ -226,70 +258,58 @@ void EEVEE_lights_cache_shcaster_material_add(
void EEVEE_lights_cache_finish(EEVEE_SceneLayerData *sldata)
{
EEVEE_LampsInfo *linfo = sldata->lamps;
+ DRWTextureFormat shadow_pool_format;
/* Setup enough layers. */
/* Free textures if number mismatch. */
- if (linfo->num_cube != linfo->cache_num_cube) {
- DRW_TEXTURE_FREE_SAFE(sldata->shadow_depth_cube_pool);
+ if ((linfo->num_shadow != linfo->cache_num_shadow) ||
+ (linfo->num_cube != linfo->cache_num_cube) ||
+ (linfo->num_cascade != linfo->cache_num_cascade))
+ {
+ DRW_TEXTURE_FREE_SAFE(sldata->shadow_pool);
linfo->cache_num_cube = linfo->num_cube;
- linfo->update_flag |= LIGHT_UPDATE_SHADOW_CUBE;
- }
- if (linfo->num_map != linfo->cache_num_map) {
- DRW_TEXTURE_FREE_SAFE(sldata->shadow_depth_map_pool);
- linfo->cache_num_map = linfo->num_map;
- }
- if (linfo->num_cascade != linfo->cache_num_cascade) {
- DRW_TEXTURE_FREE_SAFE(sldata->shadow_depth_cascade_pool);
linfo->cache_num_cascade = linfo->num_cascade;
+ linfo->cache_num_shadow = linfo->num_shadow;
+ linfo->update_flag |= LIGHT_UPDATE_SHADOW_CUBE;
}
- /* Initialize Textures Arrays first so DRW_framebuffer_init just bind them. */
- if (!sldata->shadow_depth_cube_target) {
- /* Render Cubemap */
- sldata->shadow_depth_cube_target = DRW_texture_create_cube(512, DRW_TEX_DEPTH_24, 0, NULL);
- sldata->shadow_color_cube_target = DRW_texture_create_cube(512, DRW_TEX_R_32, DRW_TEX_FILTER, NULL);
- if (sldata->shadow_cube_fb) {
- DRW_framebuffer_texture_attach(sldata->shadow_cube_fb, sldata->shadow_depth_cube_target, 0, 0);
- DRW_framebuffer_texture_attach(sldata->shadow_cube_fb, sldata->shadow_color_cube_target, 0, 0);
- }
- }
- if (!sldata->shadow_depth_cube_pool) {
- /* Cubemap / octahedral map pool */
- /* TODO Cubemap array */
- sldata->shadow_depth_cube_pool = DRW_texture_create_2D_array(
- 512, 512, max_ff(1, linfo->num_cube), DRW_TEX_R_16,
- DRW_TEX_FILTER | DRW_TEX_COMPARE, NULL);
- if (sldata->shadow_cube_fb) {
- DRW_framebuffer_texture_attach(sldata->shadow_cube_fb, sldata->shadow_depth_cube_pool, 0, 0);
- }
+ /* TODO Variance Shadow Map */
+ shadow_pool_format = DRW_TEX_R_32;
+
+ if (!sldata->shadow_cube_target) {
+ /* TODO render everything on the same 2d render target using clip planes and no Geom Shader. */
+ /* Cubemaps */
+ sldata->shadow_cube_target = DRW_texture_create_cube(linfo->shadow_cube_target_size, DRW_TEX_DEPTH_24, 0, NULL);
}
- if (!sldata->shadow_depth_map_pool) {
- sldata->shadow_depth_map_pool = DRW_texture_create_2D_array(
- 512, 512, max_ff(1, linfo->num_map), DRW_TEX_DEPTH_24,
- DRW_TEX_FILTER | DRW_TEX_COMPARE, NULL);
- if (sldata->shadow_map_fb) {
- DRW_framebuffer_texture_attach(sldata->shadow_map_fb, sldata->shadow_depth_map_pool, 0, 0);
- }
+
+ if (!sldata->shadow_cascade_target) {
+ /* CSM */
+ sldata->shadow_cascade_target = DRW_texture_create_2D_array(
+ linfo->shadow_size, linfo->shadow_size, MAX_CASCADE_NUM, DRW_TEX_DEPTH_24, 0, NULL);
}
- if (!sldata->shadow_depth_cascade_pool) {
- sldata->shadow_depth_cascade_pool = DRW_texture_create_2D_array(
- 512, 512, max_ff(1, linfo->num_cascade * MAX_CASCADE_NUM), DRW_TEX_DEPTH_24,
- DRW_TEX_FILTER | DRW_TEX_COMPARE, NULL);
- if (sldata->shadow_cascade_fb) {
- DRW_framebuffer_texture_attach(sldata->shadow_cascade_fb, sldata->shadow_depth_map_pool, 0, 0);
- }
+
+ /* Initialize Textures Array first so DRW_framebuffer_init just bind them. */
+ if (!sldata->shadow_pool) {
+ /* All shadows fit in this array */
+ sldata->shadow_pool = DRW_texture_create_2D_array(
+ linfo->shadow_size, linfo->shadow_size, max_ff(1, linfo->num_cube + linfo->num_cascade),
+ shadow_pool_format, DRW_TEX_FILTER, NULL);
}
- DRWFboTexture tex_cube_target[2] = {
- {&sldata->shadow_depth_cube_target, DRW_TEX_DEPTH_24, 0},
- {&sldata->shadow_color_cube_target, DRW_TEX_R_16, DRW_TEX_FILTER}};
- DRW_framebuffer_init(&sldata->shadow_cube_target_fb, &draw_engine_eevee_type, 512, 512, tex_cube_target, 2);
+ /* Render FB */
+ DRWFboTexture tex_cascade = {&sldata->shadow_cube_target, DRW_TEX_DEPTH_24, 0};
+ DRW_framebuffer_init(&sldata->shadow_target_fb, &draw_engine_eevee_type,
+ linfo->shadow_size, linfo->shadow_size,
+ &tex_cascade, 1);
- DRWFboTexture tex_cube = {&sldata->shadow_depth_cube_pool, DRW_TEX_R_16, DRW_TEX_FILTER};
- DRW_framebuffer_init(&sldata->shadow_cube_fb, &draw_engine_eevee_type, 512, 512, &tex_cube, 1);
+ /* Storage FB */
+ DRWFboTexture tex_pool = {&sldata->shadow_pool, shadow_pool_format, DRW_TEX_FILTER};
+ DRW_framebuffer_init(&sldata->shadow_store_fb, &draw_engine_eevee_type,
+ linfo->shadow_size, linfo->shadow_size,
+ &tex_pool, 1);
- DRWFboTexture tex_cascade = {&sldata->shadow_depth_cascade_pool, DRW_TEX_DEPTH_24, DRW_TEX_FILTER | DRW_TEX_COMPARE};
- DRW_framebuffer_init(&sldata->shadow_cascade_fb, &draw_engine_eevee_type, 512, 512, &tex_cascade, 1);
+ /* Restore */
+ DRW_framebuffer_texture_detach(sldata->shadow_cube_target);
/* Update Lamps UBOs. */
EEVEE_lights_update(sldata);
@@ -397,31 +417,6 @@ static void eevee_shadow_cube_setup(Object *ob, EEVEE_LampsInfo *linfo, EEVEE_La
evli->shadowid = (float)(evsmp->shadow_id);
}
-static void eevee_shadow_map_setup(Object *ob, EEVEE_LampsInfo *linfo, EEVEE_LampEngineData *led)
-{
- float viewmat[4][4], projmat[4][4];
-
- EEVEE_ShadowMapData *evsmp = (EEVEE_ShadowMapData *)led->storage;
- EEVEE_Light *evli = linfo->light_data + evsmp->light_id;
- EEVEE_ShadowMap *evsh = linfo->shadow_map_data + evsmp->shadow_id;
- Lamp *la = (Lamp *)ob->data;
-
- invert_m4_m4(viewmat, ob->obmat);
- normalize_v3(viewmat[0]);
- normalize_v3(viewmat[1]);
- normalize_v3(viewmat[2]);
-
- float wsize = la->shadow_frustum_size;
- orthographic_m4(projmat, -wsize, wsize, -wsize, wsize, la->clipsta, la->clipend);
-
- mul_m4_m4m4(evsmp->viewprojmat, projmat, viewmat);
- mul_m4_m4m4(evsh->shadowmat, texcomat, evsmp->viewprojmat);
-
- evsh->bias = 0.005f * la->bias;
-
- evli->shadowid = (float)(MAX_SHADOW_CUBE + evsmp->shadow_id);
-}
-
#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)
@@ -589,10 +584,10 @@ static void eevee_shadow_cascade_setup(Object *ob, EEVEE_LampsInfo *linfo, EEVEE
mul_m4_m4m4(evsh->shadowmat[c], texcomat, evscp->viewprojmat[c]);
/* TODO modify bias depending on the cascade radius */
- evsh->bias[c] = 0.005f * la->bias;
+ evsh->bias = 0.005f * la->bias;
}
- evli->shadowid = (float)(MAX_SHADOW_CUBE + MAX_SHADOW_MAP + evscp->shadow_id);
+ evli->shadowid = (float)(MAX_SHADOW_CUBE + evscp->shadow_id);
}
/* Used for checking if object is inside the shadow volume. */
@@ -718,11 +713,6 @@ void EEVEE_lights_update(EEVEE_SceneLayerData *sldata)
delete_pruned_shadowcaster(led);
}
- for (i = 0; (ob = linfo->shadow_map_ref[i]) && (i < MAX_SHADOW_MAP); i++) {
- EEVEE_LampEngineData *led = EEVEE_lamp_data_get(ob);
- eevee_shadow_map_setup(ob, linfo, led);
- }
-
for (i = 0; (ob = linfo->shadow_cascade_ref[i]) && (i < MAX_SHADOW_CASCADE); i++) {
EEVEE_LampEngineData *led = EEVEE_lamp_data_get(ob);
eevee_shadow_cascade_setup(ob, linfo, led);
@@ -738,7 +728,7 @@ void EEVEE_draw_shadows(EEVEE_SceneLayerData *sldata, EEVEE_PassList *psl)
EEVEE_LampsInfo *linfo = sldata->lamps;
Object *ob;
int i;
- float clear_color[4] = {FLT_MAX, FLT_MAX, FLT_MAX, 0.0f};
+ float clear_col[4] = {FLT_MAX};
/* Cube Shadow Maps */
/* Render each shadow to one layer of the array */
@@ -750,8 +740,10 @@ void EEVEE_draw_shadows(EEVEE_SceneLayerData *sldata, EEVEE_PassList *psl)
EEVEE_ShadowCubeData *evscd = (EEVEE_ShadowCubeData *)led->storage;
EEVEE_ShadowRender *srd = &linfo->shadow_render_data;
- srd->layer = i;
- srd->exponent = la->bleedexp;
+ srd->shadow_samples_ct = 32.0f;
+ srd->shadow_inv_samples_ct = 1.0f / srd->shadow_samples_ct;
+ srd->clip_near = la->clipsta;
+ srd->clip_far = la->clipend;
copy_v3_v3(srd->position, ob->obmat[3]);
for (int j = 0; j < 6; j++) {
float tmp[4][4];
@@ -762,15 +754,17 @@ void EEVEE_draw_shadows(EEVEE_SceneLayerData *sldata, EEVEE_PassList *psl)
copy_m4_m4(srd->shadowmat[j], evscd->viewprojmat[j]);
}
- DRW_uniformbuffer_update(sldata->shadow_render_ubo, &linfo->shadow_render_data);
+ DRW_uniformbuffer_update(sldata->shadow_render_ubo, srd);
- DRW_framebuffer_bind(sldata->shadow_cube_target_fb);
- DRW_framebuffer_clear(true, true, false, clear_color, 1.0f);
+ DRW_framebuffer_texture_attach(sldata->shadow_target_fb, sldata->shadow_cube_target, 0, 0);
+ DRW_framebuffer_bind(sldata->shadow_target_fb);
+ DRW_framebuffer_clear(true, true, false, clear_col, 1.0f);
/* Render shadow cube */
DRW_draw_pass(psl->shadow_cube_pass);
/* Push it to shadowmap array */
- DRW_framebuffer_bind(sldata->shadow_cube_fb);
+ DRW_framebuffer_texture_layer_attach(sldata->shadow_store_fb, sldata->shadow_pool, 0, i, 0);
+ DRW_framebuffer_bind(sldata->shadow_store_fb);
DRW_draw_pass(psl->shadow_cube_store_pass);
led->need_update = false;
@@ -778,21 +772,7 @@ void EEVEE_draw_shadows(EEVEE_SceneLayerData *sldata, EEVEE_PassList *psl)
}
linfo->update_flag &= ~LIGHT_UPDATE_SHADOW_CUBE;
-#if 0
- /* Standard Shadow Maps */
- DRW_framebuffer_bind(fbl->shadow_map_fb);
- DRW_framebuffer_clear(false, true, false, NULL, 1.0);
-
- /* Render each shadow to one layer of the array */
- for (i = 0; (ob = linfo->shadow_map_ref[i]) && (i < MAX_SHADOW_MAP); i++) {
- EEVEE_LampEngineData *led = EEVEE_lamp_data_get(ob);
- EEVEE_ShadowMapData *evsmd = (EEVEE_ShadowMapData *)led->storage;
-
- linfo->layer = i;
- copy_m4_m4(linfo->shadowmat, evsmd->viewprojmat);
- DRW_draw_pass(vedata->psl->shadow_pass);
- }
-#endif
+ DRW_framebuffer_texture_detach(sldata->shadow_cube_target);
/* Cascaded Shadow Maps */
// DRW_framebuffer_bind(fbl->shadow_cascade_fb);
@@ -817,5 +797,6 @@ 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_sh);
+ DRW_SHADER_FREE_SAFE(e_data.shadow_store_cube_sh);
+ DRW_SHADER_FREE_SAFE(e_data.shadow_store_cascade_sh);
} \ 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 a9425139ebf..e1852e44722 100644
--- a/source/blender/draw/engines/eevee/eevee_materials.c
+++ b/source/blender/draw/engines/eevee/eevee_materials.c
@@ -58,7 +58,6 @@
"#define MAX_PLANAR " STRINGIFY(MAX_PLANAR) "\n" \
"#define MAX_LIGHT " STRINGIFY(MAX_LIGHT) "\n" \
"#define MAX_SHADOW_CUBE " STRINGIFY(MAX_SHADOW_CUBE) "\n" \
- "#define MAX_SHADOW_MAP " STRINGIFY(MAX_SHADOW_MAP) "\n" \
"#define MAX_SHADOW_CASCADE " STRINGIFY(MAX_SHADOW_CASCADE) "\n" \
"#define MAX_CASCADE_NUM " STRINGIFY(MAX_CASCADE_NUM) "\n" \
SHADER_IRRADIANCE
@@ -370,8 +369,7 @@ static void add_standard_uniforms(
DRW_shgroup_uniform_buffer(shgrp, "probeCubes", &sldata->probe_pool);
DRW_shgroup_uniform_buffer(shgrp, "probePlanars", &vedata->txl->planar_pool);
DRW_shgroup_uniform_buffer(shgrp, "irradianceGrid", &sldata->irradiance_pool);
- DRW_shgroup_uniform_buffer(shgrp, "shadowCubes", &sldata->shadow_depth_cube_pool);
- DRW_shgroup_uniform_buffer(shgrp, "shadowCascades", &sldata->shadow_depth_cascade_pool);
+ DRW_shgroup_uniform_buffer(shgrp, "shadowTexture", &sldata->shadow_pool);
DRW_shgroup_uniform_int(shgrp, "outputSsrId", ssr_id, 1);
DRW_shgroup_uniform_vec4(shgrp, "aoParameters[0]", &vedata->stl->effects->ao_dist, 2);
if (refract_depth != NULL) {
diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h
index 723b7789377..1089fd2c5b9 100644
--- a/source/blender/draw/engines/eevee/eevee_private.h
+++ b/source/blender/draw/engines/eevee/eevee_private.h
@@ -36,7 +36,6 @@ extern struct DrawEngineType draw_engine_eevee_type;
#define MAX_PLANAR 16 /* TODO : find size by dividing UBO max size by grid data size */
#define MAX_LIGHT 128 /* TODO : find size by dividing UBO max size by light data size */
#define MAX_SHADOW_CUBE 42 /* TODO : Make this depends on GL_MAX_ARRAY_TEXTURE_LAYERS */
-#define MAX_SHADOW_MAP 64
#define MAX_SHADOW_CASCADE 8
#define MAX_CASCADE_NUM 4
#define MAX_BLOOM_STEP 16
@@ -78,12 +77,19 @@ enum {
VAR_MAT_REFRACT = (1 << 12),
};
+/* Shadow Technique */
+enum {
+ SHADOW_ESM = 1,
+ SHADOW_VSM = 2,
+};
+
typedef struct EEVEE_PassList {
/* Shadows */
struct DRWPass *shadow_pass;
struct DRWPass *shadow_cube_pass;
struct DRWPass *shadow_cube_store_pass;
struct DRWPass *shadow_cascade_pass;
+ struct DRWPass *shadow_cascade_store_pass;
/* Probes */
struct DRWPass *probe_background;
@@ -206,24 +212,22 @@ typedef struct EEVEE_ShadowCube {
float near, far, bias, exp;
} EEVEE_ShadowCube;
-typedef struct EEVEE_ShadowMap {
- float shadowmat[4][4]; /* World->Lamp->NDC->Tex : used for sampling the shadow map. */
- float near, far, bias, pad;
-} EEVEE_ShadowMap;
-
typedef struct EEVEE_ShadowCascade {
float shadowmat[MAX_CASCADE_NUM][4][4]; /* World->Lamp->NDC->Tex : used for sampling the shadow map. */
float split[4];
- float bias[4];
+ float near, far, bias, pad;
} EEVEE_ShadowCascade;
typedef struct EEVEE_ShadowRender {
- float shadowmat[6][4][4]; /* World->Lamp->NDC : used to render the shadow map. 6 frustrum for cubemap shadow */
+ float shadowmat[6][4][4]; /* World->Lamp->NDC : used to render the shadow map. 6 frustum for cubemap shadow */
float viewmat[6][4][4]; /* World->Lamp : used to render the shadow map. 6 viewmat for cubemap shadow */
- float position[3];
- float pad;
- int layer;
- float exponent;
+ float position[3], pad;
+ float cube_texel_size;
+ float stored_texel_size;
+ float clip_near;
+ float clip_far;
+ float shadow_samples_ct;
+ float shadow_inv_samples_ct;
} EEVEE_ShadowRender;
/* ************ VOLUME DATA ************ */
@@ -237,20 +241,20 @@ typedef struct EEVEE_VolumetricsInfo {
typedef struct EEVEE_LampsInfo {
int num_light, cache_num_light;
int num_cube, cache_num_cube;
- int num_map, cache_num_map;
int num_cascade, cache_num_cascade;
+ int num_shadow, cache_num_shadow;
int update_flag;
+ int shadow_size, shadow_method;
+ int shadow_cube_target_size;
/* List of lights in the scene. */
/* XXX This is fragile, can get out of sync quickly. */
struct Object *light_ref[MAX_LIGHT];
struct Object *shadow_cube_ref[MAX_SHADOW_CUBE];
- struct Object *shadow_map_ref[MAX_SHADOW_MAP];
struct Object *shadow_cascade_ref[MAX_SHADOW_CASCADE];
/* UBO Storage : data used by UBO */
struct EEVEE_Light light_data[MAX_LIGHT];
struct EEVEE_ShadowRender shadow_render_data;
struct EEVEE_ShadowCube shadow_cube_data[MAX_SHADOW_CUBE];
- struct EEVEE_ShadowMap shadow_map_data[MAX_SHADOW_MAP];
struct EEVEE_ShadowCascade shadow_cascade_data[MAX_SHADOW_CASCADE];
} EEVEE_LampsInfo;
@@ -401,17 +405,14 @@ typedef struct EEVEE_SceneLayerData {
struct GPUUniformBuffer *light_ubo;
struct GPUUniformBuffer *shadow_ubo;
struct GPUUniformBuffer *shadow_render_ubo;
+ struct GPUUniformBuffer *shadow_samples_ubo;
- struct GPUFrameBuffer *shadow_cube_target_fb;
- struct GPUFrameBuffer *shadow_cube_fb;
- struct GPUFrameBuffer *shadow_map_fb;
- struct GPUFrameBuffer *shadow_cascade_fb;
+ struct GPUFrameBuffer *shadow_target_fb;
+ struct GPUFrameBuffer *shadow_store_fb;
- struct GPUTexture *shadow_depth_cube_target;
- struct GPUTexture *shadow_color_cube_target;
- struct GPUTexture *shadow_depth_cube_pool;
- struct GPUTexture *shadow_depth_map_pool;
- struct GPUTexture *shadow_depth_cascade_pool;
+ struct GPUTexture *shadow_cube_target;
+ struct GPUTexture *shadow_cascade_target;
+ struct GPUTexture *shadow_pool;
struct ListBase shadow_casters; /* Shadow casters gathered during cache iteration */
diff --git a/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl b/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl
index fc339e93927..0da95349bba 100644
--- a/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl
@@ -19,8 +19,12 @@ layout(std140) uniform shadow_render_block {
mat4 ShadowMatrix[6];
mat4 FaceViewMatrix[6];
vec4 lampPosition;
- int layer;
- float exponent;
+ float cubeTexelSize;
+ float storedTexelSize;
+ float nearClip;
+ float farClip;
+ float shadowSampleCount;
+ float shadowInvSampleCount;
};
flat in int shFace; /* Shadow layer we are rendering to. */
@@ -72,23 +76,6 @@ struct ShadowCubeData {
vec4 near_far_bias_exp;
};
-/* convenience aliases */
-#define sh_cube_near near_far_bias_exp.x
-#define sh_cube_far near_far_bias_exp.y
-#define sh_cube_bias near_far_bias_exp.z
-#define sh_cube_exp near_far_bias_exp.w
-
-
-struct ShadowMapData {
- mat4 shadowmat;
- vec4 near_far_bias;
-};
-
-/* convenience aliases */
-#define sh_map_near near_far_bias.x
-#define sh_map_far near_far_bias.y
-#define sh_map_bias near_far_bias.z
-
#ifndef MAX_CASCADE_NUM
#define MAX_CASCADE_NUM 4
#endif
@@ -97,9 +84,15 @@ struct ShadowCascadeData {
mat4 shadowmat[MAX_CASCADE_NUM];
/* arrays of float are not aligned so use vec4 */
vec4 split_distances;
- vec4 bias;
+ vec4 near_far_bias_exp;
};
+/* convenience aliases */
+#define sh_cube_near near_far_bias_exp.x
+#define sh_cube_far near_far_bias_exp.y
+#define sh_cube_bias near_far_bias_exp.z
+#define sh_cube_exp near_far_bias_exp.w
+
/* ------- Convenience functions --------- */
vec3 mul(mat3 m, vec3 v) { return m * v; }
@@ -114,6 +107,7 @@ vec3 project_point(mat4 m, vec3 v) {
float min_v2(vec2 v) { return min(v.x, v.y); }
float min_v3(vec3 v) { return min(v.x, min(v.y, v.z)); }
float max_v2(vec2 v) { return max(v.x, v.y); }
+float max_v3(vec3 v) { return max(v.x, max(v.y, v.z)); }
float saturate(float a) { return clamp(a, 0.0, 1.0); }
vec2 saturate(vec2 a) { return clamp(a, 0.0, 1.0); }
diff --git a/source/blender/draw/engines/eevee/shaders/lamps_lib.glsl b/source/blender/draw/engines/eevee/shaders/lamps_lib.glsl
index 75ec5ade58d..79c04409161 100644
--- a/source/blender/draw/engines/eevee/shaders/lamps_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/lamps_lib.glsl
@@ -1,10 +1,8 @@
-uniform sampler2DArray shadowCubes;
-uniform sampler2DArrayShadow shadowCascades;
+uniform sampler2DArray shadowTexture;
layout(std140) uniform shadow_block {
ShadowCubeData shadows_cube_data[MAX_SHADOW_CUBE];
- ShadowMapData shadows_map_data[MAX_SHADOW_MAP];
ShadowCascadeData shadows_cascade_data[MAX_SHADOW_CASCADE];
};
@@ -26,23 +24,25 @@ float shadow_cubemap(float shid, vec4 l_vector)
vec3 cubevec = -l_vector.xyz / l_vector.w;
float dist = l_vector.w - scd.sh_cube_bias;
- float z = texture_octahedron(shadowCubes, vec4(cubevec, shid)).r;
+ float z = texture_octahedron(shadowTexture, vec4(cubevec, shid)).r;
float esm_test = saturate(exp(scd.sh_cube_exp * (z - dist)));
- // float sh_test = step(0, z - dist);
+ float sh_test = step(0, z - dist);
return esm_test;
}
float shadow_cascade(float shid, vec3 W)
{
+ return 1.0;
+ #if 0
/* Shadow Cascade */
- shid -= (MAX_SHADOW_CUBE + MAX_SHADOW_MAP);
+ shid -= MAX_SHADOW_CUBE;
ShadowCascadeData smd = shadows_cascade_data[int(shid)];
/* Finding Cascade index */
- vec4 z = vec4(-dot(cameraPos - W, cameraForward));
- vec4 comp = step(z, smd.split_distances);
+ vec4 view_z = vec4(-dot(cameraPos - W, cameraForward));
+ vec4 comp = step(view_z, smd.split_distances);
float cascade = dot(comp, comp);
mat4 shadowmat;
float bias;
@@ -68,10 +68,15 @@ float shadow_cascade(float shid, vec3 W)
}
vec4 shpos = shadowmat * vec4(W, 1.0);
- shpos.z -= bias * shpos.w;
+ float dist = shpos.z - bias * shpos.w;
shpos.xyz /= shpos.w;
- return texture(shadowCascades, vec4(shpos.xy, shid * float(MAX_CASCADE_NUM) + cascade, shpos.z));
+ float z = texture(shadowTexture, vec4(shpos.xy, shid * float(MAX_CASCADE_NUM) + cascade, shpos.z)).r;
+
+ float esm_test = saturate(exp(smd.sh_cube_exp * (z - dist)));
+
+ return esm_test;
+ #endif
}
float light_visibility(LightData ld, vec3 W, vec4 l_vector)
@@ -97,7 +102,7 @@ float light_visibility(LightData ld, vec3 W, vec4 l_vector)
#if !defined(VOLUMETRICS) || defined(VOLUME_SHADOW)
/* shadowing */
- if (ld.l_shadowid >= (MAX_SHADOW_MAP + MAX_SHADOW_CUBE)) {
+ if (ld.l_shadowid >= MAX_SHADOW_CUBE) {
vis *= shadow_cascade(ld.l_shadowid, W);
}
else if (ld.l_shadowid >= 0.0) {
diff --git a/source/blender/draw/engines/eevee/shaders/prepass_frag.glsl b/source/blender/draw/engines/eevee/shaders/prepass_frag.glsl
index cf59b29548a..f921d56e3bc 100644
--- a/source/blender/draw/engines/eevee/shaders/prepass_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/prepass_frag.glsl
@@ -62,10 +62,6 @@ float hashed_alpha_threshold(vec3 co)
uniform float alphaThreshold;
#endif
-#ifdef SHADOW_SHADER
-out vec4 FragColor;
-#endif
-
void main()
{
/* For now do nothing.
@@ -86,9 +82,4 @@ void main()
discard;
#endif
#endif
-
-#ifdef SHADOW_SHADER
- float dist = distance(lampPosition.xyz, worldPosition.xyz);
- FragColor = vec4(dist, 0.0, 0.0, 1.0);
-#endif
}
diff --git a/source/blender/draw/engines/eevee/shaders/shadow_frag.glsl b/source/blender/draw/engines/eevee/shaders/shadow_frag.glsl
index df6fbc4c2fe..160fcee4c73 100644
--- a/source/blender/draw/engines/eevee/shaders/shadow_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/shadow_frag.glsl
@@ -1,17 +1,4 @@
-layout(std140) uniform shadow_render_block {
- mat4 ShadowMatrix[6];
- mat4 FaceViewMatrix[6];
- vec4 lampPosition;
- int layer;
- float exponent;
-};
-
-in vec3 worldPosition;
-
-out vec4 FragColor;
-
void main() {
- float dist = distance(lampPosition.xyz, worldPosition.xyz);
- FragColor = vec4(dist, 0.0, 0.0, 1.0);
+ /* Do nothing */
}
diff --git a/source/blender/draw/engines/eevee/shaders/shadow_geom.glsl b/source/blender/draw/engines/eevee/shaders/shadow_geom.glsl
index 164b6a9940b..508df7a6b37 100644
--- a/source/blender/draw/engines/eevee/shaders/shadow_geom.glsl
+++ b/source/blender/draw/engines/eevee/shaders/shadow_geom.glsl
@@ -3,8 +3,12 @@ layout(std140) uniform shadow_render_block {
mat4 ShadowMatrix[6];
mat4 FaceViewMatrix[6];
vec4 lampPosition;
- int layer;
- float exponent;
+ float cubeTexelSize;
+ float storedTexelSize;
+ float nearClip;
+ float farClip;
+ float shadowSampleCount;
+ float shadowInvSampleCount;
};
layout(triangles) in;
diff --git a/source/blender/draw/engines/eevee/shaders/shadow_store_frag.glsl b/source/blender/draw/engines/eevee/shaders/shadow_store_frag.glsl
index 6782922a2e4..1c0d2556e10 100644
--- a/source/blender/draw/engines/eevee/shaders/shadow_store_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/shadow_store_frag.glsl
@@ -3,11 +3,19 @@ layout(std140) uniform shadow_render_block {
mat4 ShadowMatrix[6];
mat4 FaceViewMatrix[6];
vec4 lampPosition;
- int layer;
- float exponent;
+ float cubeTexelSize;
+ float storedTexelSize;
+ float nearClip;
+ float farClip;
+ float shadowSampleCount;
+ float shadowInvSampleCount;
};
-uniform samplerCube shadowCube;
+#ifdef CSM
+uniform sampler2DArray shadowTexture;
+#else
+uniform samplerCube shadowTexture;
+#endif
out vec4 FragColor;
@@ -25,35 +33,31 @@ vec3 octahedral_to_cubemap_proj(vec2 co)
return v;
}
-void make_orthonormal_basis(vec3 N, out vec3 T, out vec3 B)
+void make_orthonormal_basis(vec3 N, float rot, out vec3 T, out vec3 B)
{
- vec3 UpVector = abs(N.z) < 0.99999 ? vec3(0.0,0.0,1.0) : vec3(1.0,0.0,0.0);
- T = normalize( cross(UpVector, N) );
- B = cross(N, T);
+ vec3 UpVector = (abs(N.z) < max(abs(N.x), abs(N.y))) ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0);
+ vec3 nT = normalize(cross(UpVector, N));
+ vec3 nB = cross(N, nT);
+
+ /* Rotate tangent space */
+ vec2 dir = vec2(cos(rot * 3.1415 * 2.0), sin(rot * 3.1415 * 2.0));
+ T = dir.x * nT + dir.y * nB;
+ B = -dir.y * nT + dir.x * nB;
}
-#define NUM_SAMPLE 32
-vec2 poisson_disc[32] = vec2[32](
- vec2( 0.476, 0.854), vec2(-0.659, -0.670),
- vec2( 0.905, -0.270), vec2( 0.215, -0.133),
- vec2(-0.595, 0.242), vec2(-0.146, 0.519),
- vec2( 0.108, -0.930), vec2( 0.807, 0.449),
-
- vec2(-0.476, -0.854), vec2( 0.659, 0.670),
- vec2(-0.905, 0.270), vec2(-0.215, 0.133),
- vec2( 0.595, -0.242), vec2( 0.146, -0.519),
- vec2(-0.108, 0.930), vec2(-0.807, -0.449),
-
- vec2(-0.854, 0.476), vec2( 0.670, -0.659),
- vec2( 0.270, 0.905), vec2( 0.133, 0.215),
- vec2(-0.242, -0.595), vec2(-0.519, -0.146),
- vec2( 0.930, 0.108), vec2(-0.449, 0.807),
-
- vec2( 0.854, -0.476), vec2(-0.670, 0.659),
- vec2(-0.270, -0.905), vec2(-0.133, -0.215),
- vec2( 0.242, 0.595), vec2( 0.519, 0.146),
- vec2(-0.930, -0.108), vec2( 0.449, -0.807)
-);
+float linear_depth(float z)
+{
+ return (nearClip * farClip) / (z * (nearClip - farClip) + farClip);
+}
+
+float get_cube_radial_distance(vec3 cubevec)
+{
+ float zdepth = texture(shadowTexture, cubevec).r;
+ float linear_zdepth = linear_depth(zdepth);
+ cubevec = normalize(abs(cubevec));
+ float cos_vec = max(cubevec.x, max(cubevec.y, cubevec.z));
+ return linear_zdepth / cos_vec;
+}
/* Marco Salvi's GDC 2008 presentation about shadow maps pre-filtering techniques slide 24 */
float ln_space_prefilter(float w0, float x, float w1, float y)
@@ -61,14 +65,66 @@ float ln_space_prefilter(float w0, float x, float w1, float y)
return x + log(w0 + w1 * exp(y - x));
}
-void main() {
- const vec2 texelSize = vec2(1.0 / 512.0);
+const int SAMPLE_NUM = 32;
+const float INV_SAMPLE_NUM = 1.0 / float(SAMPLE_NUM);
+const vec2 poisson[32] = vec2[32](
+ vec2(-0.31889129888, 0.945170187163),
+ vec2(0.0291070069348, 0.993645382622),
+ vec2(0.453968568675, 0.882119488776),
+ vec2(-0.59142811398, 0.775098624552),
+ vec2(0.0672147039953, 0.677233646792),
+ vec2(0.632546991242, 0.60080388224),
+ vec2(-0.846282545004, 0.478266943968),
+ vec2(-0.304563967348, 0.550414788876),
+ vec2(0.343951542639, 0.482122717676),
+ vec2(0.903371461134, 0.419225918868),
+ vec2(-0.566433506581, 0.326544955645),
+ vec2(-0.0174468029403, 0.345927250589),
+ vec2(-0.970838848328, 0.131541221423),
+ vec2(-0.317404956404, 0.102175571059),
+ vec2(0.309107085158, 0.136502232088),
+ vec2(0.67009683403, 0.198922062526),
+ vec2(-0.62544683989, -0.0237682928336),
+ vec2(0.0, 0.0),
+ vec2(0.260779995092, -0.192490308513),
+ vec2(0.555635503398, -0.0918935341973),
+ vec2(0.989587880961, -0.03629312269),
+ vec2(-0.93440130633, -0.213478602005),
+ vec2(-0.615716455579, -0.335329659339),
+ vec2(0.813589336772, -0.292544036149),
+ vec2(-0.821106257666, -0.568279197395),
+ vec2(-0.298092257627, -0.457929494012),
+ vec2(0.263233114326, -0.515552889911),
+ vec2(-0.0311374378304, -0.643310533036),
+ vec2(0.785838482787, -0.615972502555),
+ vec2(-0.444079211316, -0.836548440017),
+ vec2(-0.0253421088433, -0.96112294526),
+ vec2(0.350411908643, -0.89783206142)
+);
+
+float wang_hash_noise(uint s)
+{
+ uint seed = (uint(gl_FragCoord.x) * 1664525u + uint(gl_FragCoord.y)) + s;
- vec2 uvs = gl_FragCoord.xy * texelSize;
+ seed = (seed ^ 61u) ^ (seed >> 16u);
+ seed *= 9u;
+ seed = seed ^ (seed >> 4u);
+ seed *= 0x27d4eb2du;
+ seed = seed ^ (seed >> 15u);
+
+ float value = float(seed);
+ value *= 1.0 / 4294967296.0;
+ return fract(value);
+}
+
+#define ESM
+
+void main() {
+ vec2 uvs = gl_FragCoord.xy * storedTexelSize;
/* add a 2 pixel border to ensure filtering is correct */
- uvs.xy *= 1.0 + texelSize * 2.0;
- uvs.xy -= texelSize;
+ uvs.xy *= 1.0 + storedTexelSize * 2.0;
+ uvs.xy -= storedTexelSize;
float pattern = 1.0;
@@ -86,28 +142,30 @@ void main() {
/* get cubemap vector */
vec3 cubevec = octahedral_to_cubemap_proj(uvs.xy);
+/* TODO Can be optimized by groupping fetches
+ * and by converting to radial distance beforehand. */
+#if defined(ESM)
vec3 T, B;
- make_orthonormal_basis(cubevec, T, B);
+ make_orthonormal_basis(cubevec, wang_hash_noise(0u), T, B);
+
+ T *= 0.01;
+ B *= 0.01;
- /* get cubemap shadow value */
- const float blur_radius = 5.0 / 512.0; /* Totally arbitrary */
- const float weight = 1.0 / float(NUM_SAMPLE);
float accum = 0.0;
/* Poisson disc blur in log space. */
- vec2 offsetvec = poisson_disc[0].xy * blur_radius;
- float depth1 = texture(shadowCube, cubevec + offsetvec.x * T + offsetvec.y * B).r;
-
- offsetvec = poisson_disc[1].xy * blur_radius;
- float depth2 = texture(shadowCube, cubevec + offsetvec.x * T + offsetvec.y * B).r;
+ float depth1 = get_cube_radial_distance(cubevec + poisson[0].x * T + poisson[0].y * B);
+ float depth2 = get_cube_radial_distance(cubevec + poisson[1].x * T + poisson[1].y * B);
+ accum = ln_space_prefilter(INV_SAMPLE_NUM, depth1, INV_SAMPLE_NUM, depth2);
- accum = ln_space_prefilter(weight, depth1, weight, depth2);
-
- for (int i = 2; i < NUM_SAMPLE; ++i) {
- vec2 offsetvec = poisson_disc[i].xy * blur_radius;
- depth1 = texture(shadowCube, cubevec + offsetvec.x * T + offsetvec.y * B).r;
- accum = ln_space_prefilter(1.0, accum, weight, depth1);
+ for (int i = 2; i < SAMPLE_NUM; ++i) {
+ depth1 = get_cube_radial_distance(cubevec + poisson[i].x * T + poisson[i].y * B);
+ accum = ln_space_prefilter(1.0, accum, INV_SAMPLE_NUM, depth1);
}
- FragColor = vec4(accum, accum, accum, 1.0);
+ FragColor = vec4(accum);
+
+#else /* PCF (no prefilter) */
+ FragColor = vec4(get_cube_radial_distance(cubevec));
+#endif
} \ No newline at end of file
diff --git a/source/blender/draw/engines/eevee/shaders/shadow_store_geom.glsl b/source/blender/draw/engines/eevee/shaders/shadow_store_geom.glsl
deleted file mode 100644
index 78ccb025ce6..00000000000
--- a/source/blender/draw/engines/eevee/shaders/shadow_store_geom.glsl
+++ /dev/null
@@ -1,24 +0,0 @@
-
-layout(std140) uniform shadow_render_block {
- mat4 ShadowMatrix[6];
- mat4 FaceViewMatrix[6];
- vec4 lampPosition;
- int layer;
- float exponent;
-};
-
-layout(triangles) in;
-layout(triangle_strip, max_vertices=3) out;
-
-in vec4 vPos[];
-
-void main() {
- gl_Layer = layer;
-
- for (int v = 0; v < 3; ++v) {
- gl_Position = vPos[v];
- EmitVertex();
- }
-
- EndPrimitive();
-} \ No newline at end of file
diff --git a/source/blender/draw/engines/eevee/shaders/shadow_store_vert.glsl b/source/blender/draw/engines/eevee/shaders/shadow_store_vert.glsl
deleted file mode 100644
index dee020f19b4..00000000000
--- a/source/blender/draw/engines/eevee/shaders/shadow_store_vert.glsl
+++ /dev/null
@@ -1,8 +0,0 @@
-
-in vec3 pos;
-
-out vec4 vPos;
-
-void main() {
- vPos = vec4(pos, 1.0);
-} \ No newline at end of file
diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c
index 601ea35f8c1..7d2c7819ba3 100644
--- a/source/blender/draw/intern/draw_manager.c
+++ b/source/blender/draw/intern/draw_manager.c
@@ -2222,7 +2222,9 @@ static GPUTextureFormat convert_tex_format(
case DRW_TEX_RGBA_8: *r_channels = 4; return GPU_RGBA8;
case DRW_TEX_RGBA_16: *r_channels = 4; return GPU_RGBA16F;
case DRW_TEX_RGBA_32: *r_channels = 4; return GPU_RGBA32F;
+ case DRW_TEX_DEPTH_16: *r_channels = 1; return GPU_DEPTH_COMPONENT16;
case DRW_TEX_DEPTH_24: *r_channels = 1; return GPU_DEPTH_COMPONENT24;
+ case DRW_TEX_DEPTH_32: *r_channels = 1; return GPU_DEPTH_COMPONENT32F;
case DRW_TEX_RGB_11_11_10: *r_channels = 3; return GPU_R11F_G11F_B10F;
default:
BLI_assert(false && "Texture format unsupported as render target!");