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
diff options
context:
space:
mode:
authorClément Foucault <foucault.clem@gmail.com>2017-09-08 21:21:57 +0300
committerClément Foucault <foucault.clem@gmail.com>2017-09-10 04:09:45 +0300
commit9fdf094b852652e10256fedfc6daa50beb5f83bc (patch)
tree17a98e724418ca74d6d609f5ca4f0bed81c1db49 /source/blender/draw
parentadeaf37e77dce6845fc0777183cb457dbfc1c86b (diff)
Eevee: Shadows: Filtering improvement.
- Replace poisson by concentric samples: Less variance. They are sorted by radius then by angle. - Separate filtering into 2 blur. First blur is 3x3 box blur. Second is user dependant. - Group fetches by group of 4.
Diffstat (limited to 'source/blender/draw')
-rw-r--r--source/blender/draw/CMakeLists.txt6
-rw-r--r--source/blender/draw/engines/eevee/eevee_data.c2
-rw-r--r--source/blender/draw/engines/eevee/eevee_lights.c93
-rw-r--r--source/blender/draw/engines/eevee/eevee_private.h5
-rw-r--r--source/blender/draw/engines/eevee/shaders/concentric_samples_lib.glsl267
-rw-r--r--source/blender/draw/engines/eevee/shaders/shadow_copy_frag.glsl200
-rw-r--r--source/blender/draw/engines/eevee/shaders/shadow_store_frag.glsl222
7 files changed, 621 insertions, 174 deletions
diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt
index c9f0dedfbdd..8d05e61aaa6 100644
--- a/source/blender/draw/CMakeLists.txt
+++ b/source/blender/draw/CMakeLists.txt
@@ -117,11 +117,11 @@ data_to_c_simple(engines/clay/shaders/clay_particle_strand_frag.glsl SRC)
data_to_c_simple(engines/clay/shaders/ssao_alchemy.glsl SRC)
data_to_c_simple(engines/clay/shaders/ssao_groundtruth.glsl SRC)
+data_to_c_simple(engines/eevee/shaders/ambient_occlusion_lib.glsl SRC)
data_to_c_simple(engines/eevee/shaders/default_frag.glsl SRC)
data_to_c_simple(engines/eevee/shaders/default_world_frag.glsl SRC)
data_to_c_simple(engines/eevee/shaders/background_vert.glsl SRC)
-data_to_c_simple(engines/eevee/shaders/ambient_occlusion_lib.glsl SRC)
-data_to_c_simple(engines/eevee/shaders/effect_minmaxz_frag.glsl SRC)
+data_to_c_simple(engines/eevee/shaders/concentric_samples_lib.glsl SRC)
data_to_c_simple(engines/eevee/shaders/lamps_lib.glsl SRC)
data_to_c_simple(engines/eevee/shaders/lightprobe_lib.glsl SRC)
data_to_c_simple(engines/eevee/shaders/lightprobe_filter_glossy_frag.glsl SRC)
@@ -143,6 +143,7 @@ data_to_c_simple(engines/eevee/shaders/effect_dof_frag.glsl SRC)
data_to_c_simple(engines/eevee/shaders/effect_downsample_frag.glsl SRC)
data_to_c_simple(engines/eevee/shaders/effect_downsample_cube_frag.glsl SRC)
data_to_c_simple(engines/eevee/shaders/effect_gtao_frag.glsl SRC)
+data_to_c_simple(engines/eevee/shaders/effect_minmaxz_frag.glsl SRC)
data_to_c_simple(engines/eevee/shaders/effect_motion_blur_frag.glsl SRC)
data_to_c_simple(engines/eevee/shaders/effect_ssr_frag.glsl SRC)
data_to_c_simple(engines/eevee/shaders/lightprobe_planar_downsample_frag.glsl SRC)
@@ -154,6 +155,7 @@ 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_copy_frag.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 28c049ae53e..92a992f578b 100644
--- a/source/blender/draw/engines/eevee/eevee_data.c
+++ b/source/blender/draw/engines/eevee/eevee_data.c
@@ -42,7 +42,9 @@ static void eevee_scene_layer_data_free(void *storage)
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_cube_blur);
DRW_TEXTURE_FREE_SAFE(sldata->shadow_cascade_target);
+ DRW_TEXTURE_FREE_SAFE(sldata->shadow_cascade_blur);
DRW_TEXTURE_FREE_SAFE(sldata->shadow_pool);
BLI_freelistN(&sldata->shadow_casters);
diff --git a/source/blender/draw/engines/eevee/eevee_lights.c b/source/blender/draw/engines/eevee/eevee_lights.c
index 857bdfc47f7..ca25e6e13b0 100644
--- a/source/blender/draw/engines/eevee/eevee_lights.c
+++ b/source/blender/draw/engines/eevee/eevee_lights.c
@@ -25,6 +25,8 @@
#include "DRW_render.h"
+#include "BLI_dynstr.h"
+
#include "BKE_object.h"
#include "eevee_engine.h"
@@ -57,12 +59,16 @@ static struct {
struct GPUShader *shadow_sh;
struct GPUShader *shadow_store_cube_sh[SHADOW_METHOD_MAX];
struct GPUShader *shadow_store_cascade_sh[SHADOW_METHOD_MAX];
+ struct GPUShader *shadow_copy_cube_sh[SHADOW_METHOD_MAX];
+ struct GPUShader *shadow_copy_cascade_sh[SHADOW_METHOD_MAX];
} 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_frag_glsl[];
+extern char datatoc_shadow_copy_frag_glsl[];
+extern char datatoc_concentric_samples_lib_glsl[];
/* *********** FUNCTIONS *********** */
@@ -80,13 +86,33 @@ 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[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");
+ DynStr *ds_frag = BLI_dynstr_new();
+ BLI_dynstr_append(ds_frag, datatoc_concentric_samples_lib_glsl);
+ BLI_dynstr_append(ds_frag, datatoc_shadow_store_frag_glsl);
+ char *store_shadow_shader_str = BLI_dynstr_get_cstring(ds_frag);
+ BLI_dynstr_free(ds_frag);
+
+ e_data.shadow_store_cube_sh[SHADOW_ESM] = DRW_shader_create_fullscreen(store_shadow_shader_str, "#define ESM\n");
+ e_data.shadow_store_cascade_sh[SHADOW_ESM] = DRW_shader_create_fullscreen(store_shadow_shader_str, "#define ESM\n"
+ "#define CSM\n");
+
+ e_data.shadow_store_cube_sh[SHADOW_VSM] = DRW_shader_create_fullscreen(store_shadow_shader_str, "#define VSM\n");
+ e_data.shadow_store_cascade_sh[SHADOW_VSM] = DRW_shader_create_fullscreen(store_shadow_shader_str, "#define VSM\n"
+ "#define CSM\n");
+
+ MEM_freeN(store_shadow_shader_str);
- 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");
+ e_data.shadow_copy_cube_sh[SHADOW_ESM] = DRW_shader_create_fullscreen(datatoc_shadow_copy_frag_glsl, "#define ESM\n"
+ "#define COPY\n");
+ e_data.shadow_copy_cascade_sh[SHADOW_ESM] = DRW_shader_create_fullscreen(datatoc_shadow_copy_frag_glsl, "#define ESM\n"
+ "#define COPY\n"
+ "#define CSM\n");
+
+ e_data.shadow_copy_cube_sh[SHADOW_VSM] = DRW_shader_create_fullscreen(datatoc_shadow_copy_frag_glsl, "#define VSM\n"
+ "#define COPY\n");
+ e_data.shadow_copy_cascade_sh[SHADOW_VSM] = DRW_shader_create_fullscreen(datatoc_shadow_copy_frag_glsl, "#define VSM\n"
+ "#define COPY\n"
+ "#define CSM\n");
}
if (!sldata->lamps) {
@@ -153,7 +179,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[linfo->shadow_method], psl->shadow_cascade_store_pass);
- DRW_shgroup_uniform_buffer(grp, "shadowTexture", &sldata->shadow_cascade_target);
+ DRW_shgroup_uniform_buffer(grp, "shadowTexture", &sldata->shadow_cascade_blur);
DRW_shgroup_uniform_block(grp, "shadow_render_block", sldata->shadow_render_ubo);
DRW_shgroup_uniform_int(grp, "cascadeId", &linfo->current_shadow_cascade, 1);
DRW_shgroup_uniform_float(grp, "shadowFilterSize", &linfo->filter_size, 1);
@@ -161,6 +187,28 @@ void EEVEE_lights_cache_init(EEVEE_SceneLayerData *sldata, EEVEE_PassList *psl)
}
{
+ psl->shadow_cube_copy_pass = DRW_pass_create("Shadow Copy Pass", DRW_STATE_WRITE_COLOR);
+
+ DRWShadingGroup *grp = DRW_shgroup_create(e_data.shadow_copy_cube_sh[linfo->shadow_method], psl->shadow_cube_copy_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_uniform_float(grp, "shadowFilterSize", &linfo->filter_size, 1);
+ DRW_shgroup_uniform_int(grp, "faceId", &linfo->current_shadow_face, 1);
+ DRW_shgroup_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL);
+ }
+
+ {
+ psl->shadow_cascade_copy_pass = DRW_pass_create("Shadow Cascade Copy Pass", DRW_STATE_WRITE_COLOR);
+
+ DRWShadingGroup *grp = DRW_shgroup_create(e_data.shadow_copy_cascade_sh[linfo->shadow_method], psl->shadow_cascade_copy_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_uniform_float(grp, "shadowFilterSize", &linfo->filter_size, 1);
+ DRW_shgroup_uniform_int(grp, "cascadeId", &linfo->current_shadow_cascade, 1);
+ DRW_shgroup_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL);
+ }
+
+ {
psl->shadow_cube_pass = DRW_pass_create("Shadow Cube Pass", DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS);
}
@@ -321,12 +369,15 @@ void EEVEE_lights_cache_finish(EEVEE_SceneLayerData *sldata)
/* 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);
+ sldata->shadow_cube_blur = DRW_texture_create_cube(linfo->shadow_cube_target_size, shadow_pool_format, DRW_TEX_FILTER, NULL);
}
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);
+ sldata->shadow_cascade_blur = DRW_texture_create_2D_array(
+ linfo->shadow_size, linfo->shadow_size, MAX_CASCADE_NUM, shadow_pool_format, DRW_TEX_FILTER, NULL);
}
/* Initialize Textures Array first so DRW_framebuffer_init just bind them. */
@@ -855,7 +906,6 @@ void EEVEE_draw_shadows(EEVEE_SceneLayerData *sldata, EEVEE_PassList *psl)
srd->shadow_inv_samples_ct = 1.0f / srd->shadow_samples_ct;
srd->clip_near = la->clipsta;
srd->clip_far = la->clipend;
- linfo->filter_size = la->soft * 0.0005f;
copy_v3_v3(srd->position, ob->obmat[3]);
for (int j = 0; j < 6; j++) {
float tmp[4][4];
@@ -874,7 +924,20 @@ void EEVEE_draw_shadows(EEVEE_SceneLayerData *sldata, EEVEE_PassList *psl)
/* Render shadow cube */
DRW_draw_pass(psl->shadow_cube_pass);
+ for (linfo->current_shadow_face = 0;
+ linfo->current_shadow_face < 6;
+ linfo->current_shadow_face++)
+ {
+ /* Copy using a small 3x3 box filter */
+ linfo->filter_size = (la->soft > 0.00001f) ? 1.0f : 0.0f;
+ DRW_framebuffer_cubeface_attach(sldata->shadow_store_fb, sldata->shadow_cube_blur, 0, linfo->current_shadow_face, 0);
+ DRW_framebuffer_bind(sldata->shadow_store_fb);
+ DRW_draw_pass(psl->shadow_cube_copy_pass);
+ DRW_framebuffer_texture_detach(sldata->shadow_cube_blur);
+ }
+
/* Push it to shadowmap array */
+ linfo->filter_size = la->soft * 0.0005f;
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);
@@ -914,9 +977,15 @@ void EEVEE_draw_shadows(EEVEE_SceneLayerData *sldata, EEVEE_PassList *psl)
linfo->current_shadow_cascade < la->cascade_count;
++linfo->current_shadow_cascade)
{
- linfo->filter_size = la->soft * 0.0005f / (evscd->radius[linfo->current_shadow_cascade] * 0.05f);
+ /* Copy using a small 3x3 box filter */
+ linfo->filter_size = (la->soft > 0.00001f) ? 1.0f : 0.0f;
+ DRW_framebuffer_texture_layer_attach(sldata->shadow_store_fb, sldata->shadow_cascade_blur, 0, linfo->current_shadow_cascade, 0);
+ DRW_framebuffer_bind(sldata->shadow_store_fb);
+ DRW_draw_pass(psl->shadow_cascade_copy_pass);
+ DRW_framebuffer_texture_detach(sldata->shadow_cascade_blur);
- /* Push it to shadowmap array */
+ /* Push it to shadowmap array and blur more */
+ linfo->filter_size = la->soft * 0.0005f / (evscd->radius[linfo->current_shadow_cascade] * 0.05f);
int layer = evscd->layer_id + linfo->current_shadow_cascade;
DRW_framebuffer_texture_layer_attach(sldata->shadow_store_fb, sldata->shadow_pool, 0, layer, 0);
DRW_framebuffer_bind(sldata->shadow_store_fb);
@@ -924,7 +993,7 @@ void EEVEE_draw_shadows(EEVEE_SceneLayerData *sldata, EEVEE_PassList *psl)
}
}
- DRW_framebuffer_texture_detach(sldata->shadow_cube_target);
+ DRW_framebuffer_texture_detach(sldata->shadow_cascade_target);
}
void EEVEE_lights_free(void)
@@ -933,5 +1002,7 @@ void EEVEE_lights_free(void)
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]);
+ DRW_SHADER_FREE_SAFE(e_data.shadow_copy_cube_sh[i]);
+ DRW_SHADER_FREE_SAFE(e_data.shadow_copy_cascade_sh[i]);
}
} \ No newline at end of file
diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h
index 65b1ddfd949..72bd04a5958 100644
--- a/source/blender/draw/engines/eevee/eevee_private.h
+++ b/source/blender/draw/engines/eevee/eevee_private.h
@@ -91,8 +91,10 @@ typedef struct EEVEE_PassList {
/* Shadows */
struct DRWPass *shadow_pass;
struct DRWPass *shadow_cube_pass;
+ struct DRWPass *shadow_cube_copy_pass;
struct DRWPass *shadow_cube_store_pass;
struct DRWPass *shadow_cascade_pass;
+ struct DRWPass *shadow_cascade_copy_pass;
struct DRWPass *shadow_cascade_store_pass;
/* Probes */
@@ -257,6 +259,7 @@ typedef struct EEVEE_LampsInfo {
bool shadow_high_bitdepth;
int shadow_cube_target_size;
int current_shadow_cascade;
+ int current_shadow_face;
float filter_size;
/* List of lights in the scene. */
/* XXX This is fragile, can get out of sync quickly. */
@@ -424,7 +427,9 @@ typedef struct EEVEE_SceneLayerData {
struct GPUFrameBuffer *shadow_store_fb;
struct GPUTexture *shadow_cube_target;
+ struct GPUTexture *shadow_cube_blur;
struct GPUTexture *shadow_cascade_target;
+ struct GPUTexture *shadow_cascade_blur;
struct GPUTexture *shadow_pool;
struct ListBase shadow_casters; /* Shadow casters gathered during cache iteration */
diff --git a/source/blender/draw/engines/eevee/shaders/concentric_samples_lib.glsl b/source/blender/draw/engines/eevee/shaders/concentric_samples_lib.glsl
new file mode 100644
index 00000000000..67bcf603a81
--- /dev/null
+++ b/source/blender/draw/engines/eevee/shaders/concentric_samples_lib.glsl
@@ -0,0 +1,267 @@
+/* Precomputed table of concentric samples.
+ * Generated using this algorithm http://l2program.co.uk/900/concentric-disk-sampling
+ * Sorted by radius then by rotation angle.
+ * This way it's better for cache usage and for
+ * easily restricting to a certain number of
+ * sample while still having a circular kernel. */
+
+#define CONCENTRIC_SAMPLE_NUM 256
+const vec2 concentric[CONCENTRIC_SAMPLE_NUM] =
+vec2[CONCENTRIC_SAMPLE_NUM](
+ vec2(0.0441941738242, 0.0441941738242),
+ vec2(-0.0441941738242, -0.0441941738242),
+ vec2(-0.0441941738242, 0.0441941738242),
+ vec2(0.0441941738242, -0.0441941738242),
+ vec2(0.181111092429, 0.0485285709567),
+ vec2(0.132582521472, 0.132582521472),
+ vec2(-0.181111092429, 0.0485285709567),
+ vec2(0.0485285709567, 0.181111092429),
+ vec2(-0.181111092429, -0.0485285709567),
+ vec2(-0.0485285709567, 0.181111092429),
+ vec2(-0.132582521472, -0.132582521472),
+ vec2(-0.132582521472, 0.132582521472),
+ vec2(-0.0485285709567, -0.181111092429),
+ vec2(0.0485285709567, -0.181111092429),
+ vec2(0.132582521472, -0.132582521472),
+ vec2(0.181111092429, -0.0485285709567),
+ vec2(0.308652606436, 0.0488857703251),
+ vec2(0.278439538809, 0.141872031169),
+ vec2(0.220970869121, 0.220970869121),
+ vec2(-0.278439538809, 0.141872031169),
+ vec2(0.141872031169, 0.278439538809),
+ vec2(-0.308652606436, 0.0488857703251),
+ vec2(0.0488857703251, 0.308652606436),
+ vec2(-0.308652606436, -0.0488857703251),
+ vec2(-0.0488857703251, 0.308652606436),
+ vec2(-0.278439538809, -0.141872031169),
+ vec2(-0.141872031169, 0.278439538809),
+ vec2(-0.220970869121, -0.220970869121),
+ vec2(-0.220970869121, 0.220970869121),
+ vec2(-0.141872031169, -0.278439538809),
+ vec2(-0.0488857703251, -0.308652606436),
+ vec2(0.0488857703251, -0.308652606436),
+ vec2(0.141872031169, -0.278439538809),
+ vec2(0.220970869121, -0.220970869121),
+ vec2(0.278439538809, -0.141872031169),
+ vec2(0.308652606436, -0.0488857703251),
+ vec2(0.434749091828, 0.0489844582952),
+ vec2(0.41294895701, 0.144497089605),
+ vec2(0.370441837162, 0.232764033475),
+ vec2(0.309359216769, 0.309359216769),
+ vec2(-0.370441837162, 0.232764033475),
+ vec2(0.232764033475, 0.370441837162),
+ vec2(-0.41294895701, 0.144497089605),
+ vec2(0.144497089605, 0.41294895701),
+ vec2(-0.434749091828, 0.0489844582952),
+ vec2(0.0489844582952, 0.434749091828),
+ vec2(-0.434749091828, -0.0489844582952),
+ vec2(-0.0489844582952, 0.434749091828),
+ vec2(-0.41294895701, -0.144497089605),
+ vec2(-0.144497089605, 0.41294895701),
+ vec2(-0.370441837162, -0.232764033475),
+ vec2(-0.232764033475, 0.370441837162),
+ vec2(-0.309359216769, -0.309359216769),
+ vec2(-0.309359216769, 0.309359216769),
+ vec2(-0.232764033475, -0.370441837162),
+ vec2(-0.144497089605, -0.41294895701),
+ vec2(-0.0489844582952, -0.434749091828),
+ vec2(0.0489844582952, -0.434749091828),
+ vec2(0.144497089605, -0.41294895701),
+ vec2(0.232764033475, -0.370441837162),
+ vec2(0.309359216769, -0.309359216769),
+ vec2(0.370441837162, -0.232764033475),
+ vec2(0.41294895701, -0.144497089605),
+ vec2(0.434749091828, -0.0489844582952),
+ vec2(0.560359517677, 0.0490251052956),
+ vec2(0.543333277288, 0.14558571287),
+ vec2(0.509798130208, 0.237722772229),
+ vec2(0.460773024913, 0.322636745447),
+ vec2(0.397747564417, 0.397747564417),
+ vec2(-0.460773024913, 0.322636745447),
+ vec2(0.322636745447, 0.460773024913),
+ vec2(-0.509798130208, 0.237722772229),
+ vec2(0.237722772229, 0.509798130208),
+ vec2(-0.543333277288, 0.14558571287),
+ vec2(0.14558571287, 0.543333277288),
+ vec2(-0.560359517677, 0.0490251052956),
+ vec2(0.0490251052956, 0.560359517677),
+ vec2(-0.560359517677, -0.0490251052956),
+ vec2(-0.0490251052956, 0.560359517677),
+ vec2(-0.543333277288, -0.14558571287),
+ vec2(-0.14558571287, 0.543333277288),
+ vec2(-0.509798130208, -0.237722772229),
+ vec2(-0.237722772229, 0.509798130208),
+ vec2(-0.460773024913, -0.322636745447),
+ vec2(-0.322636745447, 0.460773024913),
+ vec2(-0.397747564417, -0.397747564417),
+ vec2(-0.397747564417, 0.397747564417),
+ vec2(-0.322636745447, -0.460773024913),
+ vec2(-0.237722772229, -0.509798130208),
+ vec2(-0.14558571287, -0.543333277288),
+ vec2(-0.0490251052956, -0.560359517677),
+ vec2(0.0490251052956, -0.560359517677),
+ vec2(0.14558571287, -0.543333277288),
+ vec2(0.237722772229, -0.509798130208),
+ vec2(0.322636745447, -0.460773024913),
+ vec2(0.397747564417, -0.397747564417),
+ vec2(0.460773024913, -0.322636745447),
+ vec2(0.509798130208, -0.237722772229),
+ vec2(0.543333277288, -0.14558571287),
+ vec2(0.560359517677, -0.0490251052956),
+ vec2(0.685748328795, 0.0490456884495),
+ vec2(0.671788470355, 0.146138636568),
+ vec2(0.644152935937, 0.240256623474),
+ vec2(0.603404305327, 0.32948367837),
+ vec2(0.550372103135, 0.412003395727),
+ vec2(0.486135912066, 0.486135912066),
+ vec2(-0.550372103135, 0.412003395727),
+ vec2(0.412003395727, 0.550372103135),
+ vec2(-0.603404305327, 0.32948367837),
+ vec2(0.32948367837, 0.603404305327),
+ vec2(-0.644152935937, 0.240256623474),
+ vec2(0.240256623474, 0.644152935937),
+ vec2(-0.671788470355, 0.146138636568),
+ vec2(0.146138636568, 0.671788470355),
+ vec2(-0.685748328795, 0.0490456884495),
+ vec2(0.0490456884495, 0.685748328795),
+ vec2(-0.685748328795, -0.0490456884495),
+ vec2(-0.0490456884495, 0.685748328795),
+ vec2(-0.671788470355, -0.146138636568),
+ vec2(-0.146138636568, 0.671788470355),
+ vec2(-0.644152935937, -0.240256623474),
+ vec2(-0.240256623474, 0.644152935937),
+ vec2(-0.603404305327, -0.32948367837),
+ vec2(-0.32948367837, 0.603404305327),
+ vec2(-0.550372103135, -0.412003395727),
+ vec2(-0.412003395727, 0.550372103135),
+ vec2(-0.486135912066, -0.486135912066),
+ vec2(-0.486135912066, 0.486135912066),
+ vec2(-0.412003395727, -0.550372103135),
+ vec2(-0.32948367837, -0.603404305327),
+ vec2(-0.240256623474, -0.644152935937),
+ vec2(-0.146138636568, -0.671788470355),
+ vec2(-0.0490456884495, -0.685748328795),
+ vec2(0.0490456884495, -0.685748328795),
+ vec2(0.146138636568, -0.671788470355),
+ vec2(0.240256623474, -0.644152935937),
+ vec2(0.32948367837, -0.603404305327),
+ vec2(0.412003395727, -0.550372103135),
+ vec2(0.486135912066, -0.486135912066),
+ vec2(0.550372103135, -0.412003395727),
+ vec2(0.603404305327, -0.32948367837),
+ vec2(0.644152935937, -0.240256623474),
+ vec2(0.671788470355, -0.146138636568),
+ vec2(0.685748328795, -0.0490456884495),
+ vec2(0.811017637806, 0.0490575291556),
+ vec2(0.799191174395, 0.146457218224),
+ vec2(0.775710704038, 0.241721231257),
+ vec2(0.740918624869, 0.33346040443),
+ vec2(0.695322283745, 0.420336974019),
+ vec2(0.639586577995, 0.501084084011),
+ vec2(0.574524259714, 0.574524259714),
+ vec2(-0.639586577995, 0.501084084011),
+ vec2(0.501084084011, 0.639586577995),
+ vec2(-0.695322283745, 0.420336974019),
+ vec2(0.420336974019, 0.695322283745),
+ vec2(-0.740918624869, 0.33346040443),
+ vec2(0.33346040443, 0.740918624869),
+ vec2(-0.775710704038, 0.241721231257),
+ vec2(0.241721231257, 0.775710704038),
+ vec2(-0.799191174395, 0.146457218224),
+ vec2(0.146457218224, 0.799191174395),
+ vec2(-0.811017637806, 0.0490575291556),
+ vec2(0.0490575291556, 0.811017637806),
+ vec2(-0.811017637806, -0.0490575291556),
+ vec2(-0.0490575291556, 0.811017637806),
+ vec2(-0.799191174395, -0.146457218224),
+ vec2(-0.146457218224, 0.799191174395),
+ vec2(-0.775710704038, -0.241721231257),
+ vec2(-0.241721231257, 0.775710704038),
+ vec2(-0.740918624869, -0.33346040443),
+ vec2(-0.33346040443, 0.740918624869),
+ vec2(-0.695322283745, -0.420336974019),
+ vec2(-0.420336974019, 0.695322283745),
+ vec2(-0.639586577995, -0.501084084011),
+ vec2(-0.501084084011, 0.639586577995),
+ vec2(-0.574524259714, -0.574524259714),
+ vec2(-0.574524259714, 0.574524259714),
+ vec2(-0.501084084011, -0.639586577995),
+ vec2(-0.420336974019, -0.695322283745),
+ vec2(-0.33346040443, -0.740918624869),
+ vec2(-0.241721231257, -0.775710704038),
+ vec2(-0.146457218224, -0.799191174395),
+ vec2(-0.0490575291556, -0.811017637806),
+ vec2(0.0490575291556, -0.811017637806),
+ vec2(0.146457218224, -0.799191174395),
+ vec2(0.241721231257, -0.775710704038),
+ vec2(0.33346040443, -0.740918624869),
+ vec2(0.420336974019, -0.695322283745),
+ vec2(0.501084084011, -0.639586577995),
+ vec2(0.574524259714, -0.574524259714),
+ vec2(0.639586577995, -0.501084084011),
+ vec2(0.695322283745, -0.420336974019),
+ vec2(0.740918624869, -0.33346040443),
+ vec2(0.775710704038, -0.241721231257),
+ vec2(0.799191174395, -0.146457218224),
+ vec2(0.811017637806, -0.0490575291556),
+ vec2(0.936215188832, 0.0490649589778),
+ vec2(0.925957819308, 0.146657310975),
+ vec2(0.905555462146, 0.242642854784),
+ vec2(0.875231649841, 0.335969952699),
+ vec2(0.835318616427, 0.425616093506),
+ vec2(0.786253657449, 0.510599095327),
+ vec2(0.728574338866, 0.589987866609),
+ vec2(0.662912607362, 0.662912607362),
+ vec2(-0.728574338866, 0.589987866609),
+ vec2(0.589987866609, 0.728574338866),
+ vec2(-0.786253657449, 0.510599095327),
+ vec2(0.510599095327, 0.786253657449),
+ vec2(-0.835318616427, 0.425616093506),
+ vec2(0.425616093506, 0.835318616427),
+ vec2(-0.875231649841, 0.335969952699),
+ vec2(0.335969952699, 0.875231649841),
+ vec2(-0.905555462146, 0.242642854784),
+ vec2(0.242642854784, 0.905555462146),
+ vec2(-0.925957819308, 0.146657310975),
+ vec2(0.146657310975, 0.925957819308),
+ vec2(-0.936215188832, 0.0490649589778),
+ vec2(0.0490649589778, 0.936215188832),
+ vec2(-0.936215188832, -0.0490649589778),
+ vec2(-0.0490649589778, 0.936215188832),
+ vec2(-0.925957819308, -0.146657310975),
+ vec2(-0.146657310975, 0.925957819308),
+ vec2(-0.905555462146, -0.242642854784),
+ vec2(-0.242642854784, 0.905555462146),
+ vec2(-0.875231649841, -0.335969952699),
+ vec2(-0.335969952699, 0.875231649841),
+ vec2(-0.835318616427, -0.425616093506),
+ vec2(-0.425616093506, 0.835318616427),
+ vec2(-0.786253657449, -0.510599095327),
+ vec2(-0.510599095327, 0.786253657449),
+ vec2(-0.728574338866, -0.589987866609),
+ vec2(-0.589987866609, 0.728574338866),
+ vec2(-0.662912607362, -0.662912607362),
+ vec2(-0.662912607362, 0.662912607362),
+ vec2(-0.589987866609, -0.728574338866),
+ vec2(-0.510599095327, -0.786253657449),
+ vec2(-0.425616093506, -0.835318616427),
+ vec2(-0.335969952699, -0.875231649841),
+ vec2(-0.242642854784, -0.905555462146),
+ vec2(-0.146657310975, -0.925957819308),
+ vec2(-0.0490649589778, -0.936215188832),
+ vec2(0.0490649589778, -0.936215188832),
+ vec2(0.146657310975, -0.925957819308),
+ vec2(0.242642854784, -0.905555462146),
+ vec2(0.335969952699, -0.875231649841),
+ vec2(0.425616093506, -0.835318616427),
+ vec2(0.510599095327, -0.786253657449),
+ vec2(0.589987866609, -0.728574338866),
+ vec2(0.662912607362, -0.662912607362),
+ vec2(0.728574338866, -0.589987866609),
+ vec2(0.786253657449, -0.510599095327),
+ vec2(0.835318616427, -0.425616093506),
+ vec2(0.875231649841, -0.335969952699),
+ vec2(0.905555462146, -0.242642854784),
+ vec2(0.925957819308, -0.146657310975),
+ vec2(0.936215188832, -0.0490649589778)
+); \ No newline at end of file
diff --git a/source/blender/draw/engines/eevee/shaders/shadow_copy_frag.glsl b/source/blender/draw/engines/eevee/shaders/shadow_copy_frag.glsl
new file mode 100644
index 00000000000..b70d6faa73d
--- /dev/null
+++ b/source/blender/draw/engines/eevee/shaders/shadow_copy_frag.glsl
@@ -0,0 +1,200 @@
+/* Copy the depth only shadowmap into another texture while converting
+ * to linear depth (or other storage method) and doing a 3x3 box filter. */
+
+layout(std140) uniform shadow_render_block {
+ mat4 ShadowMatrix[6];
+ mat4 FaceViewMatrix[6];
+ vec4 lampPosition;
+ float cubeTexelSize;
+ float storedTexelSize;
+ float nearClip;
+ float farClip;
+ float shadowSampleCount;
+ float shadowInvSampleCount;
+};
+
+#ifdef CSM
+uniform sampler2DArray shadowTexture;
+uniform int cascadeId;
+#else
+uniform samplerCube shadowTexture;
+uniform vec3 cubeFaceVec[3];
+#endif
+uniform float shadowFilterSize;
+
+out vec4 FragColor;
+
+float linear_depth(float z)
+{
+ return (nearClip * farClip) / (z * (nearClip - farClip) + farClip);
+}
+
+vec4 linear_depth(vec4 z)
+{
+ return (nearClip * farClip) / (z * (nearClip - farClip) + farClip);
+}
+
+#ifdef CSM
+vec4 get_world_distance(vec4 depths, vec3 cos[4])
+{
+ /* Background case */
+ vec4 is_background = step(vec4(0.99999), depths);
+ depths *= abs(farClip - nearClip); /* Same factor as in shadow_cascade(). */
+ depths += 1e1 * is_background;
+ return depths;
+}
+
+float get_world_distance(float depth, vec3 cos)
+{
+ /* Background case */
+ float is_background = step(0.9999, depth);
+ depth *= abs(farClip - nearClip); /* Same factor as in shadow_cascade(). */
+ depth += 1e1 * is_background;
+ return depth;
+}
+#else /* CUBEMAP */
+vec4 get_world_distance(vec4 depths, vec3 cos[4])
+{
+ vec4 is_background = step(vec4(1.0), depths);
+ depths = linear_depth(depths);
+ depths += vec4(1e16) * is_background;
+ cos[0] = normalize(abs(cos[0]));
+ cos[1] = normalize(abs(cos[1]));
+ cos[2] = normalize(abs(cos[2]));
+ cos[3] = normalize(abs(cos[3]));
+ vec4 cos_vec;
+ cos_vec.x = max(cos[0].x, max(cos[0].y, cos[0].z));
+ cos_vec.y = max(cos[1].x, max(cos[1].y, cos[1].z));
+ cos_vec.z = max(cos[2].x, max(cos[2].y, cos[2].z));
+ cos_vec.w = max(cos[3].x, max(cos[3].y, cos[3].z));
+ return depths / cos_vec;
+}
+
+float get_world_distance(float depth, vec3 cos)
+{
+ float is_background = step(1.0, depth);
+ depth = linear_depth(depth);
+ depth += 1e16 * is_background;
+ cos = normalize(abs(cos));
+ float cos_vec = max(cos.x, max(cos.y, cos.z));
+ return depth / cos_vec;
+}
+#endif
+
+/* 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)
+{
+ return x + log(w0 + w1 * exp(y - x));
+}
+
+#define SAMPLE_WEIGHT 0.11111
+
+#ifdef ESM
+void filter(vec4 depths, inout float accum)
+{
+ accum = ln_space_prefilter(1.0, accum, SAMPLE_WEIGHT, depths.x);
+ accum = ln_space_prefilter(1.0, accum, SAMPLE_WEIGHT, depths.y);
+ accum = ln_space_prefilter(1.0, accum, SAMPLE_WEIGHT, depths.z);
+ accum = ln_space_prefilter(1.0, accum, SAMPLE_WEIGHT, depths.w);
+}
+#else /* VSM */
+void filter(vec4 depths, inout vec2 accum)
+{
+ vec4 depths_sqr = depths * depths;
+ accum += vec2(dot(vec4(1.0), depths), dot(vec4(1.0), depths_sqr)) * SAMPLE_WEIGHT;
+}
+#endif
+
+#ifdef CSM
+vec3 get_texco(vec2 uvs, vec2 ofs)
+{
+ return vec3(uvs + ofs, float(cascadeId));
+}
+#else /* CUBEMAP */
+const vec3 minorAxisX[6] = vec3[6](
+ vec3(0.0f, 0.0f, -1.0f),
+ vec3(0.0f, 0.0f, 1.0f),
+ vec3(1.0f, 0.0f, 0.0f),
+ vec3(1.0f, 0.0f, 0.0f),
+ vec3(1.0f, 0.0f, 0.0f),
+ vec3(-1.0f, 0.0f, 0.0f)
+);
+
+const vec3 minorAxisY[6] = vec3[6](
+ vec3(0.0f, -1.0f, 0.0f),
+ vec3(0.0f, -1.0f, 0.0f),
+ vec3(0.0f, 0.0f, -1.0f),
+ vec3(0.0f, 0.0f, 1.0f),
+ vec3(0.0f, -1.0f, 0.0f),
+ vec3(0.0f, -1.0f, 0.0f)
+);
+
+const vec3 majorAxis[6] = vec3[6](
+ vec3(-1.0f, 0.0f, 0.0f),
+ vec3(1.0f, 0.0f, 0.0f),
+ vec3(0.0f, 1.0f, 0.0f),
+ vec3(0.0f, -1.0f, 0.0f),
+ vec3(0.0f, 0.0f, -1.0f),
+ vec3(0.0f, 0.0f, 1.0f)
+);
+
+vec3 get_texco(vec2 uvs, vec2 ofs)
+{
+ uvs += ofs;
+ return majorAxis[0] + uvs.x * minorAxisX[1] + uvs.y * minorAxisY[2];
+}
+#endif
+
+void main() {
+ /* Copy the depth only shadowmap into another texture while converting
+ * to linear depth and do a 3x3 box blur. */
+
+#ifdef CSM
+ vec2 uvs = gl_FragCoord.xy * storedTexelSize;
+#else /* CUBEMAP */
+ vec2 uvs = gl_FragCoord.xy * cubeTexelSize;
+#endif
+
+ /* Center texel */
+ vec3 co = get_texco(uvs, vec2(0.0));
+ float depth = texture(shadowTexture, co).r;
+ depth = get_world_distance(depth, co);
+#ifdef ESM
+ float accum = ln_space_prefilter(0.0, 0.0, SAMPLE_WEIGHT, depth);
+#else /* VSM */
+ vec2 accum = vec2(depth, depth * depth) * SAMPLE_WEIGHT;
+#endif
+
+#ifdef CSM
+ vec3 ofs = storedTexelSize * vec3(1.0, 0.0, -1.0) * shadowFilterSize;
+#else /* CUBEMAP */
+ vec3 ofs = cubeTexelSize * vec3(1.0, 0.0, -1.0) * shadowFilterSize;
+#endif
+
+ vec3 cos[4];
+ cos[0] = get_texco(uvs, ofs.zz);
+ cos[1] = get_texco(uvs, ofs.yz);
+ cos[2] = get_texco(uvs, ofs.xz);
+ cos[3] = get_texco(uvs, ofs.zy);
+
+ vec4 depths;
+ depths.x = texture(shadowTexture, cos[0]).r;
+ depths.y = texture(shadowTexture, cos[1]).r;
+ depths.z = texture(shadowTexture, cos[2]).r;
+ depths.w = texture(shadowTexture, cos[3]).r;
+ depths = get_world_distance(depths, cos);
+ filter(depths, accum);
+
+ cos[0] = get_texco(uvs, ofs.xy);
+ cos[1] = get_texco(uvs, ofs.zx);
+ cos[2] = get_texco(uvs, ofs.yx);
+ cos[3] = get_texco(uvs, ofs.xx);
+ depths.x = texture(shadowTexture, cos[0]).r;
+ depths.y = texture(shadowTexture, cos[1]).r;
+ depths.z = texture(shadowTexture, cos[2]).r;
+ depths.w = texture(shadowTexture, cos[3]).r;
+ depths = get_world_distance(depths, cos);
+ filter(depths, accum);
+
+ FragColor = vec2(accum).xyxy;
+}
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 6564fd87d04..c14107198aa 100644
--- a/source/blender/draw/engines/eevee/shaders/shadow_store_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/shadow_store_frag.glsl
@@ -35,212 +35,112 @@ vec3 octahedral_to_cubemap_proj(vec2 co)
return v;
}
-void make_orthonormal_basis(vec3 N, float rot, out vec3 T, out vec3 B)
+void make_orthonormal_basis(vec3 N, out vec3 T, out vec3 B)
{
vec3 UpVector = (abs(N.z) < 0.999) ? 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 */
- float angle = rot * 3.1415 * 2.0;
- vec2 dir = vec2(cos(angle), sin(angle));
- T = dir.x * nT + dir.y * nB;
- B = -dir.y * nT + dir.x * nB;
+/* 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)
+{
+ return x + log(w0 + w1 * exp(y - x));
}
-float linear_depth(float z)
+vec4 ln_space_prefilter(float w0, vec4 x, float w1, vec4 y)
{
- return (nearClip * farClip) / (z * (nearClip - farClip) + farClip);
+ return x + log(w0 + w1 * exp(y - x));
}
+/* globals */
+vec3 T, B;
+
#ifdef CSM
-float get_cascade_world_distance(vec2 uvs)
+vec3 get_texco(vec3 cos, vec2 ofs)
{
- float zdepth = texture(shadowTexture, vec3(uvs, float(cascadeId))).r;
- if (zdepth == 1.0) {
- /* Background case */
- return 1e16;
- }
- return zdepth * abs(farClip - nearClip); /* Same factor as in shadow_cascade(). */
+ cos.xy += ofs * shadowFilterSize;
+ return cos;
}
-#else
-float get_cube_radial_distance(vec3 cubevec)
+#else /* CUBEMAP */
+vec3 get_texco(vec3 cos, vec2 ofs)
{
- 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;
+ return cos + ofs.x * T + ofs.y * B;
}
#endif
-/* 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)
-{
- return x + log(w0 + w1 * exp(y - x));
-}
-
-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;
-
- seed = (seed ^ 61u) ^ (seed >> 16u);
- seed *= 9u;
- seed = seed ^ (seed >> 4u);
- seed *= 0x27d4eb2du;
- seed = seed ^ (seed >> 15u);
+const float INV_SAMPLE_NUM = 1.0 / float(CONCENTRIC_SAMPLE_NUM);
- float value = float(seed);
- value *= 1.0 / 4294967296.0;
- return fract(value);
-}
-
-#ifdef CSM
void main() {
- vec2 uvs = gl_FragCoord.xy * storedTexelSize;
-
- vec2 X, Y;
- X.x = cos(wang_hash_noise(0u) * 3.1415 * 2.0);
- X.y = sqrt(1.0 - X.x * X.x);
-
- Y = vec2(-X.y, X.x);
+ vec3 cos;
- X *= shadowFilterSize;
- Y *= shadowFilterSize;
-
-/* TODO Can be optimized by groupping fetches
- * and by converting to world distance beforehand. */
-#if defined(ESM) || defined(VSM)
-#ifdef ESM
- float accum = 0.0;
-
- /* Poisson disc blur in log space. */
- float depth1 = get_cascade_world_distance(uvs + X * poisson[0].x + Y * poisson[0].y);
- float depth2 = get_cascade_world_distance(uvs + X * poisson[1].x + Y * poisson[1].y);
- accum = ln_space_prefilter(INV_SAMPLE_NUM, depth1, INV_SAMPLE_NUM, depth2);
-
- for (int i = 2; i < SAMPLE_NUM; ++i) {
- depth1 = get_cascade_world_distance(uvs + X * poisson[i].x + Y * poisson[i].y);
- accum = ln_space_prefilter(1.0, accum, INV_SAMPLE_NUM, depth1);
- }
-
- FragColor = vec4(accum);
-#else /* VSM */
- vec2 accum = vec2(0.0);
-
- /* Poisson disc blur. */
- for (int i = 0; i < SAMPLE_NUM; ++i) {
- float dist = get_cascade_world_distance(uvs + X * poisson[i].x + Y * poisson[i].y);
- float dist_sqr = dist * dist;
- accum += vec2(dist, dist_sqr);
- }
-
- FragColor = accum.xyxy * shadowInvSampleCount;
-#endif /* Prefilter */
-#else /* PCF (no prefilter) */
- FragColor = vec4(get_cascade_world_distance(uvs));
-#endif
-}
+ cos.xy = gl_FragCoord.xy * storedTexelSize;
+#ifdef CSM
+ cos.z = float(cascadeId);
#else /* CUBEMAP */
-
-void main() {
- vec2 uvs = gl_FragCoord.xy * storedTexelSize;
-
/* add a 2 pixel border to ensure filtering is correct */
- uvs.xy *= 1.0 + storedTexelSize * 2.0;
- uvs.xy -= storedTexelSize;
+ cos.xy *= 1.0 + storedTexelSize * 2.0;
+ cos.xy -= storedTexelSize;
float pattern = 1.0;
/* edge mirroring : only mirror if directly adjacent
* (not diagonally adjacent) */
- vec2 m = abs(uvs - 0.5) + 0.5;
+ vec2 m = abs(cos.xy - 0.5) + 0.5;
vec2 f = floor(m);
if (f.x - f.y != 0.0) {
- uvs.xy = 1.0 - uvs.xy;
+ cos.xy = 1.0 - cos.xy;
}
/* clamp to [0-1] */
- uvs.xy = fract(uvs.xy);
+ cos.xy = fract(cos.xy);
/* get cubemap vector */
- vec3 cubevec = normalize(octahedral_to_cubemap_proj(uvs.xy));
-
-/* TODO Can be optimized by groupping fetches
- * and by converting to radial distance beforehand. */
-#if defined(ESM) || defined(VSM)
- vec3 T, B;
- make_orthonormal_basis(cubevec, wang_hash_noise(0u), T, B);
+ cos = normalize(octahedral_to_cubemap_proj(cos.xy));
+ make_orthonormal_basis(cos, T, B);
T *= shadowFilterSize;
B *= shadowFilterSize;
+#endif
#ifdef ESM
- float accum = 0.0;
-
- /* Poisson disc blur in log space. */
- 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);
-
- 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);
+ vec4 accum = vec4(0.0);
+
+ /* disc blur in log space. */
+ vec4 depths;
+ depths.x = texture(shadowTexture, get_texco(cos, concentric[0])).r;
+ depths.y = texture(shadowTexture, get_texco(cos, concentric[1])).r;
+ depths.z = texture(shadowTexture, get_texco(cos, concentric[2])).r;
+ depths.w = texture(shadowTexture, get_texco(cos, concentric[3])).r;
+ accum = ln_space_prefilter(0.0, accum, INV_SAMPLE_NUM, depths);
+
+ for (int i = 4; i < CONCENTRIC_SAMPLE_NUM; i += 4) {
+ depths.x = texture(shadowTexture, get_texco(cos, concentric[i+0])).r;
+ depths.y = texture(shadowTexture, get_texco(cos, concentric[i+1])).r;
+ depths.z = texture(shadowTexture, get_texco(cos, concentric[i+2])).r;
+ depths.w = texture(shadowTexture, get_texco(cos, concentric[i+3])).r;
+ accum = ln_space_prefilter(1.0, accum, INV_SAMPLE_NUM, depths);
}
- FragColor = vec4(accum);
+ accum.x = ln_space_prefilter(1.0, accum.x, 1.0, accum.y);
+ accum.x = ln_space_prefilter(1.0, accum.x, 1.0, accum.z);
+ accum.x = ln_space_prefilter(1.0, accum.x, 1.0, accum.w);
+ FragColor = accum.xxxx;
+
#else /* VSM */
vec2 accum = vec2(0.0);
- /* Poisson disc blur. */
- for (int i = 0; i < SAMPLE_NUM; ++i) {
- float dist = get_cube_radial_distance(cubevec + poisson[i].x * T + poisson[i].y * B);
- float dist_sqr = dist * dist;
- accum += vec2(dist, dist_sqr);
+ /* disc blur. */
+ vec4 depths1, depths2;
+ for (int i = 0; i < CONCENTRIC_SAMPLE_NUM; i += 4) {
+ depths1.xy = texture(shadowTexture, get_texco(cos, concentric[i+0])).rg;
+ depths1.zw = texture(shadowTexture, get_texco(cos, concentric[i+1])).rg;
+ depths2.xy = texture(shadowTexture, get_texco(cos, concentric[i+2])).rg;
+ depths2.zw = texture(shadowTexture, get_texco(cos, concentric[i+3])).rg;
+ accum += depths1.xy + depths1.zw + depths2.xy + depths2.zw;
}
- FragColor = accum.xyxy * shadowInvSampleCount;
-#endif /* Prefilter */
-#else /* PCF (no prefilter) */
- FragColor = vec4(get_cube_radial_distance(cubevec));
+ FragColor = accum.xyxy * INV_SAMPLE_NUM;
#endif
-}
-#endif \ No newline at end of file
+} \ No newline at end of file