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.
This commit is contained in:
parent
adeaf37e77
commit
9fdf094b85
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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_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_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_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,13 +179,35 @@ 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);
|
||||
DRW_shgroup_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL);
|
||||
}
|
||||
|
||||
{
|
||||
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]);
|
||||
}
|
||||
}
|
|
@ -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 */
|
||||
|
|
|
@ -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)
|
||||
);
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
float linear_depth(float z)
|
||||
{
|
||||
return (nearClip * farClip) / (z * (nearClip - farClip) + farClip);
|
||||
}
|
||||
|
||||
#ifdef CSM
|
||||
float get_cascade_world_distance(vec2 uvs)
|
||||
{
|
||||
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(). */
|
||||
}
|
||||
#else
|
||||
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;
|
||||
}
|
||||
#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)
|
||||
vec4 ln_space_prefilter(float w0, vec4 x, float w1, vec4 y)
|
||||
{
|
||||
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);
|
||||
|
||||
float value = float(seed);
|
||||
value *= 1.0 / 4294967296.0;
|
||||
return fract(value);
|
||||
return x + log(w0 + w1 * exp(y - x));
|
||||
}
|
||||
|
||||
/* globals */
|
||||
vec3 T, B;
|
||||
|
||||
#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);
|
||||
|
||||
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
|
||||
vec3 get_texco(vec3 cos, vec2 ofs)
|
||||
{
|
||||
cos.xy += ofs * shadowFilterSize;
|
||||
return cos;
|
||||
}
|
||||
|
||||
#else /* CUBEMAP */
|
||||
vec3 get_texco(vec3 cos, vec2 ofs)
|
||||
{
|
||||
return cos + ofs.x * T + ofs.y * B;
|
||||
}
|
||||
#endif
|
||||
|
||||
const float INV_SAMPLE_NUM = 1.0 / float(CONCENTRIC_SAMPLE_NUM);
|
||||
|
||||
void main() {
|
||||
vec2 uvs = gl_FragCoord.xy * storedTexelSize;
|
||||
vec3 cos;
|
||||
|
||||
cos.xy = gl_FragCoord.xy * storedTexelSize;
|
||||
|
||||
#ifdef CSM
|
||||
cos.z = float(cascadeId);
|
||||
#else /* CUBEMAP */
|
||||
/* 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;
|
||||
vec4 accum = vec4(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);
|
||||
/* 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 = 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);
|
||||
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
|
||||
}
|
Loading…
Reference in New Issue