diff options
11 files changed, 248 insertions, 151 deletions
diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt index a7432211160..3bfa9a15ce3 100644 --- a/source/blender/draw/CMakeLists.txt +++ b/source/blender/draw/CMakeLists.txt @@ -131,6 +131,9 @@ data_to_c_simple(engines/eevee/shaders/probe_vert.glsl SRC) 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/bsdf_direct_lib.glsl SRC) data_to_c_simple(engines/eevee/shaders/bsdf_common_lib.glsl SRC) diff --git a/source/blender/draw/engines/eevee/eevee_engine.c b/source/blender/draw/engines/eevee/eevee_engine.c index fcbc3f073ff..01363ef878d 100644 --- a/source/blender/draw/engines/eevee/eevee_engine.c +++ b/source/blender/draw/engines/eevee/eevee_engine.c @@ -56,8 +56,6 @@ static struct { struct GPUShader *default_world; struct GPUShader *default_background; struct GPUShader *depth_sh; - struct GPUShader *tonemap; - struct GPUShader *shadow_sh; struct GPUShader *probe_filter_sh; struct GPUShader *probe_spherical_harmonic_sh; @@ -263,11 +261,6 @@ static void EEVEE_engine_init(void *ved) MEM_freeN(frag_str); } - 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); - } - if (!e_data.default_world) { e_data.default_world = DRW_shader_create( datatoc_probe_vert_glsl, datatoc_probe_geom_glsl, datatoc_default_world_frag_glsl, NULL); @@ -341,32 +334,6 @@ static DRWShadingGroup *eevee_cube_shgroup(struct GPUShader *sh, DRWPass *pass, return grp; } -static DRWShadingGroup *eevee_cube_shadow_shgroup( - EEVEE_PassList *psl, EEVEE_StorageList *stl, struct Batch *geom, float (*obmat)[4]) -{ - DRWShadingGroup *grp = DRW_shgroup_instance_create(e_data.shadow_sh, psl->shadow_cube_pass, geom); - DRW_shgroup_uniform_block(grp, "shadow_render_block", stl->shadow_render_ubo); - DRW_shgroup_uniform_mat4(grp, "ShadowModelMatrix", (float *)obmat); - - for (int i = 0; i < 6; ++i) - DRW_shgroup_call_dynamic_add_empty(grp); - - return grp; -} - -static DRWShadingGroup *eevee_cascade_shadow_shgroup( - EEVEE_PassList *psl, EEVEE_StorageList *stl, struct Batch *geom, float (*obmat)[4]) -{ - DRWShadingGroup *grp = DRW_shgroup_instance_create(e_data.shadow_sh, psl->shadow_cascade_pass, geom); - DRW_shgroup_uniform_block(grp, "shadow_render_block", stl->shadow_render_ubo); - DRW_shgroup_uniform_mat4(grp, "ShadowModelMatrix", (float *)obmat); - - for (int i = 0; i < MAX_CASCADE_NUM; ++i) - DRW_shgroup_call_dynamic_add_empty(grp); - - return grp; -} - static void EEVEE_cache_init(void *vedata) { static int zero = 0; @@ -381,14 +348,6 @@ static void EEVEE_cache_init(void *vedata) } { - psl->shadow_cube_pass = DRW_pass_create("Shadow Cube Pass", DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS); - } - - { - psl->shadow_cascade_pass = DRW_pass_create("Shadow Cascade Pass", DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS); - } - - { // psl->shadow_pass = DRW_pass_create("Shadow Pass", DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS); // stl->g_data->shadow_shgrp = DRW_shgroup_create(e_data.shadow_sh, psl->shadow_pass); // DRW_shgroup_uniform_mat4(stl->g_data->shadow_shgrp, "ShadowMatrix", (float *)stl->lamps->shadowmat); @@ -556,7 +515,7 @@ static void EEVEE_cache_init(void *vedata) } - EEVEE_lights_cache_init(stl); + EEVEE_lights_cache_init(stl, psl, txl); EEVEE_effects_cache_init(vedata); } @@ -683,8 +642,11 @@ static void EEVEE_cache_populate(void *vedata, Object *ob) // GPUMaterial *gpumat = GPU_material_from_nodetree(struct bNodeTree *ntree, ListBase *gpumaterials, void *engine_type, int options) // DRW_shgroup_call_add(stl->g_data->shadow_shgrp, geom, ob->obmat); - eevee_cascade_shadow_shgroup(psl, stl, geom, ob->obmat); - eevee_cube_shadow_shgroup(psl, stl, geom, ob->obmat); + const bool cast_shadow = true; + + if (cast_shadow) { + EEVEE_lights_cache_shcaster_add(psl, stl, geom, ob->obmat); + } } else if (ob->type == OB_LAMP) { EEVEE_lights_cache_add(stl, ob); @@ -692,7 +654,6 @@ static void EEVEE_cache_populate(void *vedata, Object *ob) } typedef struct eevee_bind_shadow_data { - struct GPUTexture *shadow_depth_map_pool; struct GPUTexture *shadow_depth_cube_pool; struct GPUTexture *shadow_depth_cascade_pool; } eevee_bind_shadow_data; @@ -700,7 +661,6 @@ typedef struct eevee_bind_shadow_data { static void eevee_bind_shadow(void *data, DRWShadingGroup *shgrp) { eevee_bind_shadow_data *shdw_data = data; - DRW_shgroup_uniform_texture(shgrp, "shadowMaps", shdw_data->shadow_depth_map_pool); DRW_shgroup_uniform_texture(shgrp, "shadowCubes", shdw_data->shadow_depth_cube_pool); DRW_shgroup_uniform_texture(shgrp, "shadowCascades", shdw_data->shadow_depth_cascade_pool); } @@ -717,7 +677,6 @@ static void EEVEE_cache_finish(void *vedata) /* Shadows binding */ eevee_bind_shadow_data data; - data.shadow_depth_map_pool = txl->shadow_depth_map_pool; data.shadow_depth_cube_pool = txl->shadow_depth_cube_pool; data.shadow_depth_cascade_pool = txl->shadow_depth_cascade_pool; @@ -757,11 +716,11 @@ static void EEVEE_draw_scene(void *vedata) static void EEVEE_engine_free(void) { EEVEE_effects_free(); + EEVEE_lights_free(); MEM_SAFE_FREE(e_data.frag_shader_lib); DRW_SHADER_FREE_SAFE(e_data.default_lit); DRW_SHADER_FREE_SAFE(e_data.default_lit_flat); - DRW_SHADER_FREE_SAFE(e_data.shadow_sh); DRW_SHADER_FREE_SAFE(e_data.default_world); DRW_SHADER_FREE_SAFE(e_data.default_background); DRW_SHADER_FREE_SAFE(e_data.probe_filter_sh); diff --git a/source/blender/draw/engines/eevee/eevee_lights.c b/source/blender/draw/engines/eevee/eevee_lights.c index aeeb25ca1c0..7adc2696746 100644 --- a/source/blender/draw/engines/eevee/eevee_lights.c +++ b/source/blender/draw/engines/eevee/eevee_lights.c @@ -47,6 +47,18 @@ typedef struct EEVEE_ShadowCascadeData { float viewprojmat[MAX_CASCADE_NUM][4][4]; /* World->Lamp->NDC : used for rendering the shadow map. */ } EEVEE_ShadowCascadeData; +static struct { + struct GPUShader *shadow_sh; + struct GPUShader *shadow_store_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 *********** */ void EEVEE_lights_init(EEVEE_StorageList *stl) @@ -55,6 +67,14 @@ void EEVEE_lights_init(EEVEE_StorageList *stl) sizeof(EEVEE_ShadowMap) * MAX_SHADOW_MAP + sizeof(EEVEE_ShadowCascade) * MAX_SHADOW_CASCADE; + 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); + } + if (!stl->lamps) { stl->lamps = MEM_callocN(sizeof(EEVEE_LampsInfo), "EEVEE_LampsInfo"); stl->light_ubo = DRW_uniformbuffer_create(sizeof(EEVEE_Light) * MAX_LIGHT, NULL); @@ -63,7 +83,7 @@ void EEVEE_lights_init(EEVEE_StorageList *stl) } } -void EEVEE_lights_cache_init(EEVEE_StorageList *stl) +void EEVEE_lights_cache_init(EEVEE_StorageList *stl, EEVEE_PassList *psl, EEVEE_TextureList *txl) { EEVEE_LampsInfo *linfo = stl->lamps; @@ -72,6 +92,23 @@ void EEVEE_lights_cache_init(EEVEE_StorageList *stl) 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", &txl->shadow_color_cube_target); + DRW_shgroup_uniform_block(grp, "shadow_render_block", stl->shadow_render_ubo); + 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); + } + + { + psl->shadow_cascade_pass = DRW_pass_create("Shadow Cascade Pass", DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS); + } } void EEVEE_lights_cache_add(EEVEE_StorageList *stl, Object *ob) @@ -89,7 +126,7 @@ void EEVEE_lights_cache_add(EEVEE_StorageList *stl, Object *ob) DRW_lamp_engine_data_free((void *)led); -#if 0 /* TODO Waiting for notified refresh. only on scene change. Else too much perf cost. */ +#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) { led->sto = MEM_mallocN(sizeof(EEVEE_ShadowCascadeData), "EEVEE_ShadowCascadeData"); @@ -119,6 +156,24 @@ void EEVEE_lights_cache_add(EEVEE_StorageList *stl, Object *ob) } } +/* Add a shadow caster to the shadowpasses */ +void EEVEE_lights_cache_shcaster_add(EEVEE_PassList *psl, EEVEE_StorageList *stl, struct Batch *geom, float (*obmat)[4]) +{ + DRWShadingGroup *grp = DRW_shgroup_instance_create(e_data.shadow_sh, psl->shadow_cube_pass, geom); + DRW_shgroup_uniform_block(grp, "shadow_render_block", stl->shadow_render_ubo); + DRW_shgroup_uniform_mat4(grp, "ShadowModelMatrix", (float *)obmat); + + for (int i = 0; i < 6; ++i) + DRW_shgroup_call_dynamic_add_empty(grp); + + grp = DRW_shgroup_instance_create(e_data.shadow_sh, psl->shadow_cascade_pass, geom); + DRW_shgroup_uniform_block(grp, "shadow_render_block", stl->shadow_render_ubo); + DRW_shgroup_uniform_mat4(grp, "ShadowModelMatrix", (float *)obmat); + + for (int i = 0; i < MAX_CASCADE_NUM; ++i) + DRW_shgroup_call_dynamic_add_empty(grp); +} + void EEVEE_lights_cache_finish(EEVEE_StorageList *stl, EEVEE_TextureList *txl, EEVEE_FramebufferList *fbl) { EEVEE_LampsInfo *linfo = stl->lamps; @@ -141,10 +196,21 @@ void EEVEE_lights_cache_finish(EEVEE_StorageList *stl, EEVEE_TextureList *txl, E linfo->cache_num_cascade = linfo->num_cascade; } - /* Initialize Textures Arrays first so DRW_framebuffer_init just bind them */ + /* Initialize Textures Arrays first so DRW_framebuffer_init just bind them. */ + if (!txl->shadow_depth_cube_target) { + /* Render Cubemap */ + txl->shadow_depth_cube_target = DRW_texture_create_cube(512, DRW_TEX_DEPTH_24, 0, NULL); + txl->shadow_color_cube_target = DRW_texture_create_cube(512, DRW_TEX_R_32, 0, NULL); + if (fbl->shadow_cube_fb) { + DRW_framebuffer_texture_attach(fbl->shadow_cube_fb, txl->shadow_depth_cube_target, 0, 0); + DRW_framebuffer_texture_attach(fbl->shadow_cube_fb, txl->shadow_color_cube_target, 0, 0); + } + } if (!txl->shadow_depth_cube_pool) { + /* Cubemap / octahedra map pool */ + /* TODO Cubemap array */ txl->shadow_depth_cube_pool = DRW_texture_create_2D_array( - 512, 512, max_ff(1, linfo->num_cube * 6), DRW_TEX_DEPTH_24, + 512, 512, max_ff(1, linfo->num_cube), DRW_TEX_R_32, DRW_TEX_FILTER | DRW_TEX_COMPARE, NULL); if (fbl->shadow_cube_fb) { DRW_framebuffer_texture_attach(fbl->shadow_cube_fb, txl->shadow_depth_cube_pool, 0, 0); @@ -167,11 +233,13 @@ void EEVEE_lights_cache_finish(EEVEE_StorageList *stl, EEVEE_TextureList *txl, E } } - DRWFboTexture tex_cube = {&txl->shadow_depth_cube_pool, DRW_TEX_DEPTH_24, DRW_TEX_FILTER | DRW_TEX_COMPARE}; - DRW_framebuffer_init(&fbl->shadow_cube_fb, &draw_engine_eevee_type, 512, 512, &tex_cube, 1); + DRWFboTexture tex_cube_target[2] = { + {&txl->shadow_depth_cube_target, DRW_TEX_DEPTH_24, 0}, + {&txl->shadow_color_cube_target, DRW_TEX_R_32, 0}}; + DRW_framebuffer_init(&fbl->shadow_cube_target_fb, &draw_engine_eevee_type, 512, 512, tex_cube_target, 2); - DRWFboTexture tex_map = {&txl->shadow_depth_map_pool, DRW_TEX_DEPTH_24, DRW_TEX_FILTER | DRW_TEX_COMPARE}; - DRW_framebuffer_init(&fbl->shadow_map_fb, &draw_engine_eevee_type, 512, 512, &tex_map, 1); + DRWFboTexture tex_cube = {&txl->shadow_depth_cube_pool, DRW_TEX_R_32, DRW_TEX_FILTER}; + DRW_framebuffer_init(&fbl->shadow_cube_fb, &draw_engine_eevee_type, 512, 512, &tex_cube, 1); DRWFboTexture tex_cascade = {&txl->shadow_depth_cascade_pool, DRW_TEX_DEPTH_24, DRW_TEX_FILTER | DRW_TEX_COMPARE}; DRW_framebuffer_init(&fbl->shadow_cascade_fb, &draw_engine_eevee_type, 512, 512, &tex_cascade, 1); @@ -515,14 +583,9 @@ void EEVEE_draw_shadows(EEVEE_Data *vedata) EEVEE_LampsInfo *linfo = stl->lamps; Object *ob; int i; + float clear_color[4] = {0.0f, 0.0f, 0.0f, 0.0f}; /* Cube Shadow Maps */ - /* For old hardware support, we render each face of the shadow map - * onto 6 layer of a big 2D texture array and sample manualy the right layer - * in the fragment shader. */ - DRW_framebuffer_bind(fbl->shadow_cube_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_cube_ref[i]) && (i < MAX_SHADOW_CUBE); i++) { EEVEE_LampEngineData *led = (EEVEE_LampEngineData *)DRW_lamp_engine_data_get(ob, &DRW_engine_viewport_eevee_type); @@ -530,12 +593,20 @@ void EEVEE_draw_shadows(EEVEE_Data *vedata) EEVEE_ShadowRender *srd = &linfo->shadow_render_data; srd->layer = i; + copy_v3_v3(srd->position, ob->obmat[3]); for (int j = 0; j < 6; ++j) { copy_m4_m4(srd->shadowmat[j], evscd->viewprojmat[j]); } DRW_uniformbuffer_update(stl->shadow_render_ubo, &linfo->shadow_render_data); + DRW_framebuffer_bind(fbl->shadow_cube_target_fb); + DRW_framebuffer_clear(true, true, false, clear_color, 1.0); + /* Render shadow cube */ DRW_draw_pass(psl->shadow_cube_pass); + + /* Push it to shadowmap array */ + DRW_framebuffer_bind(fbl->shadow_cube_fb); + DRW_draw_pass(psl->shadow_cube_store_pass); } #if 0 @@ -555,21 +626,27 @@ void EEVEE_draw_shadows(EEVEE_Data *vedata) #endif /* Cascaded Shadow Maps */ - DRW_framebuffer_bind(fbl->shadow_cascade_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_cascade_ref[i]) && (i < MAX_SHADOW_CASCADE); i++) { - EEVEE_LampEngineData *led = (EEVEE_LampEngineData *)DRW_lamp_engine_data_get(ob, &DRW_engine_viewport_eevee_type); - EEVEE_ShadowCascadeData *evscd = (EEVEE_ShadowCascadeData *)led->sto; - EEVEE_ShadowRender *srd = &linfo->shadow_render_data; - - srd->layer = i; - for (int j = 0; j < MAX_CASCADE_NUM; ++j) { - copy_m4_m4(srd->shadowmat[j], evscd->viewprojmat[j]); - } - DRW_uniformbuffer_update(stl->shadow_render_ubo, &linfo->shadow_render_data); - - DRW_draw_pass(psl->shadow_cascade_pass); - } +// DRW_framebuffer_bind(fbl->shadow_cascade_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_cascade_ref[i]) && (i < MAX_SHADOW_CASCADE); i++) { +// EEVEE_LampEngineData *led = (EEVEE_LampEngineData *)DRW_lamp_engine_data_get(ob, &DRW_engine_viewport_eevee_type); +// EEVEE_ShadowCascadeData *evscd = (EEVEE_ShadowCascadeData *)led->sto; +// EEVEE_ShadowRender *srd = &linfo->shadow_render_data; + +// srd->layer = i; +// for (int j = 0; j < MAX_CASCADE_NUM; ++j) { +// copy_m4_m4(srd->shadowmat[j], evscd->viewprojmat[j]); +// } +// DRW_uniformbuffer_update(stl->shadow_render_ubo, &linfo->shadow_render_data); + +// DRW_draw_pass(psl->shadow_cascade_pass); +// } } + +void EEVEE_lights_free(void) +{ + DRW_SHADER_FREE_SAFE(e_data.shadow_sh); + DRW_SHADER_FREE_SAFE(e_data.shadow_store_sh); +}
\ 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 b9b8287c1f4..bc0bbf9f139 100644 --- a/source/blender/draw/engines/eevee/eevee_private.h +++ b/source/blender/draw/engines/eevee/eevee_private.h @@ -42,6 +42,7 @@ 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; /* Probes */ @@ -69,6 +70,7 @@ typedef struct EEVEE_PassList { typedef struct EEVEE_FramebufferList { /* Shadows */ + struct GPUFrameBuffer *shadow_cube_target_fb; struct GPUFrameBuffer *shadow_cube_fb; struct GPUFrameBuffer *shadow_map_fb; struct GPUFrameBuffer *shadow_cascade_fb; @@ -90,6 +92,8 @@ typedef struct EEVEE_FramebufferList { typedef struct EEVEE_TextureList { /* Shadows */ + 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; @@ -157,6 +161,8 @@ typedef struct 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 position[3]; + float pad; int layer; } EEVEE_ShadowRender; @@ -263,11 +269,13 @@ typedef struct EEVEE_PrivateData { /* eevee_lights.c */ void EEVEE_lights_init(EEVEE_StorageList *stl); -void EEVEE_lights_cache_init(EEVEE_StorageList *stl); +void EEVEE_lights_cache_init(EEVEE_StorageList *stl, EEVEE_PassList *psl, EEVEE_TextureList *txl); void EEVEE_lights_cache_add(EEVEE_StorageList *stl, struct Object *ob); +void EEVEE_lights_cache_shcaster_add(EEVEE_PassList *psl, EEVEE_StorageList *stl, struct Batch *geom, float (*obmat)[4]); void EEVEE_lights_cache_finish(EEVEE_StorageList *stl, EEVEE_TextureList *txl, EEVEE_FramebufferList *fbl); void EEVEE_lights_update(EEVEE_StorageList *stl); void EEVEE_draw_shadows(EEVEE_Data *vedata); +void EEVEE_lights_free(void); /* eevee_probes.c */ void EEVEE_probes_init(EEVEE_Data *vedata); @@ -305,13 +313,13 @@ static const float cubefacemat[6][4][4] = { {0.0, 0.0, 0.0, 1.0}}, /* Pos Y */ {{1.0, 0.0, 0.0, 0.0}, - {0.0, 0.0, 1.0, 0.0}, - {0.0, -1.0, 0.0, 0.0}, + {0.0, 0.0, -1.0, 0.0}, + {0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, 0.0, 1.0}}, /* Neg Y */ {{1.0, 0.0, 0.0, 0.0}, - {0.0, 0.0, -1.0, 0.0}, - {0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0}, + {0.0, -1.0, 0.0, 0.0}, {0.0, 0.0, 0.0, 1.0}}, /* Pos Z */ {{1.0, 0.0, 0.0, 0.0}, diff --git a/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl b/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl index 1e29aed739d..1c124c06744 100644 --- a/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl @@ -11,8 +11,7 @@ uniform vec3 shCoefs[9]; #ifndef USE_LTC uniform sampler2D brdfLut; #endif -uniform sampler2DArrayShadow shadowCubes; -uniform sampler2DArrayShadow shadowMaps; +uniform sampler2DArray shadowCubes; uniform sampler2DArrayShadow shadowCascades; layout(std140) uniform light_block { @@ -130,75 +129,30 @@ float light_visibility(LightData ld, ShadingData sd) vis *= texture(shadowCascades, vec4(shpos.xy, shid * float(MAX_CASCADE_NUM) + cascade, shpos.z)); } - else if (ld.l_shadowid >= MAX_SHADOW_CUBE) { - /* Shadow Map */ - float shid = ld.l_shadowid - MAX_SHADOW_CUBE; - ShadowMapData smd = shadows_map_data[int(shid)]; - vec4 shpos = smd.shadowmat * vec4(sd.W, 1.0); - shpos.z -= smd.sh_map_bias * shpos.w; - shpos.xyz /= shpos.w; - - if (shpos.w > 0.0 && min(shpos.x, shpos.y) > 0.0 && max(shpos.x, shpos.y) < 1.0) { - vis *= texture(shadowMaps, vec4(shpos.xy, shid, shpos.z)); - } - } else { /* Shadow Cube */ float shid = ld.l_shadowid; ShadowCubeData scd = shadows_cube_data[int(shid)]; - float face; - vec2 uvs; - vec3 Linv = sd.L; - vec3 Labs = abs(Linv); - vec3 maj_axis; - - if (max(Labs.y, Labs.z) < Labs.x) { - if (Linv.x > 0.0) { - face = 1.0; - uvs = vec2(1.0, -1.0) * Linv.zy / -Linv.x; - maj_axis = vec3(1.0, 0.0, 0.0); - } - else { - face = 0.0; - uvs = -Linv.zy / Linv.x; - maj_axis = vec3(-1.0, 0.0, 0.0); - } - } - else if (max(Labs.x, Labs.z) < Labs.y) { - if (Linv.y > 0.0) { - face = 2.0; - uvs = vec2(-1.0, 1.0) * Linv.xz / Linv.y; - maj_axis = vec3(0.0, 1.0, 0.0); - } - else { - face = 3.0; - uvs = -Linv.xz / -Linv.y; - maj_axis = vec3(0.0, -1.0, 0.0); - } - } - else { - if (Linv.z > 0.0) { - face = 5.0; - uvs = Linv.xy / Linv.z; - maj_axis = vec3(0.0, 0.0, 1.0); - } - else { - face = 4.0; - uvs = vec2(-1.0, 1.0) * Linv.xy / -Linv.z; - maj_axis = vec3(0.0, 0.0, -1.0); - } + vec3 cubevec = sd.W - ld.l_position; + float dist = length(cubevec); + + /* projection onto octahedron */ + cubevec /= dot( vec3(1), abs(cubevec) ); + + /* out-folding of the downward faces */ + if ( cubevec.z < 0.0 ) { + cubevec.xy = (1.0 - abs(cubevec.yx)) * sign(cubevec.xy); } + vec2 texelSize = vec2(1.0 / 512.0); - uvs = uvs * 0.5 + 0.5; + /* mapping to [0;1]ˆ2 texture space */ + vec2 uvs = cubevec.xy * (0.5) + 0.5; + uvs = uvs * (1.0 - 2.0 * texelSize) + 1.0 * texelSize; /* edge filtering fix */ - /* Depth in lightspace to compare against shadow map */ - float w = dot(maj_axis, sd.l_vector); - w -= scd.sh_map_bias * w; - bool is_persp = (ProjectionMatrix[3][3] == 0.0); - float shdepth = buffer_depth(is_persp, w, scd.sh_cube_far, scd.sh_cube_near); + float sh_test = step(0, texture(shadowCubes, vec3(uvs, shid)).r - dist); - vis *= texture(shadowCubes, vec4(uvs, shid * 6.0 + face, shdepth)); + vis *= sh_test; } return vis; diff --git a/source/blender/draw/engines/eevee/shaders/shadow_frag.glsl b/source/blender/draw/engines/eevee/shaders/shadow_frag.glsl index 29335207851..0b7356d812b 100644 --- a/source/blender/draw/engines/eevee/shaders/shadow_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/shadow_frag.glsl @@ -1,3 +1,8 @@ +in float linearDistance; + +out vec4 FragColor; + void main() { + FragColor = vec4(linearDistance, 0.0, 0.0, 1.0); } diff --git a/source/blender/draw/engines/eevee/shaders/shadow_geom.glsl b/source/blender/draw/engines/eevee/shaders/shadow_geom.glsl index bac6a10eee1..c4738de2f31 100644 --- a/source/blender/draw/engines/eevee/shaders/shadow_geom.glsl +++ b/source/blender/draw/engines/eevee/shaders/shadow_geom.glsl @@ -1,21 +1,26 @@ -layout(triangles) in; -layout(triangle_strip, max_vertices=3) out; - layout(std140) uniform shadow_render_block { mat4 ShadowMatrix[6]; - int Layer; + vec4 lampPosition; + int layer; }; +layout(triangles) in; +layout(triangle_strip, max_vertices=3) out; + in vec4 vPos[]; +in float lDist[]; flat in int face[]; +out float linearDistance; + void main() { int f = face[0]; - gl_Layer = Layer + f; + gl_Layer = f; for (int v = 0; v < 3; ++v) { gl_Position = ShadowMatrix[f] * vPos[v]; + linearDistance = lDist[v]; EmitVertex(); } diff --git a/source/blender/draw/engines/eevee/shaders/shadow_store_frag.glsl b/source/blender/draw/engines/eevee/shaders/shadow_store_frag.glsl new file mode 100644 index 00000000000..08453080ed2 --- /dev/null +++ b/source/blender/draw/engines/eevee/shaders/shadow_store_frag.glsl @@ -0,0 +1,47 @@ + +uniform samplerCube shadowCube; + +out vec4 FragColor; + +vec3 octahedral_to_cubemap_proj(vec2 co) +{ + co = co * 2.0 - 1.0; + + vec2 abs_co = abs(co); + vec3 v = vec3(co, 1.0 - (abs_co.x + abs_co.y)); + + if ( abs_co.x + abs_co.y > 1.0 ) { + v.xy = (abs(co.yx) - 1.0) * -sign(co.xy); + } + + return v; +} + +void main() { + const vec2 texelSize = vec2(1.0 / 512.0); + + vec2 uvs = gl_FragCoord.xy * texelSize; + + /* add a 2 pixel border to ensure filtering is correct */ + uvs.xy *= 1.0 + texelSize * 2.0; + uvs.xy -= texelSize; + + float pattern = 1.0; + + /* edge mirroring : only mirror if directly adjacent + * (not diagonally adjacent) */ + vec2 m = abs(uvs - 0.5) + 0.5; + vec2 f = floor(m); + if (f.x - f.y != 0.0) { + uvs.xy = 1.0 - uvs.xy; + } + + /* clamp to [0-1] */ + uvs.xy = fract(uvs.xy); + + /* get cubemap vector */ + vec3 cubevec = octahedral_to_cubemap_proj(uvs.xy); + + /* get cubemap vector */ + FragColor = texture(shadowCube, cubevec).rrrr; +}
\ 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 new file mode 100644 index 00000000000..f14354ad4cd --- /dev/null +++ b/source/blender/draw/engines/eevee/shaders/shadow_store_geom.glsl @@ -0,0 +1,22 @@ + +layout(std140) uniform shadow_render_block { + mat4 ShadowMatrix[6]; + vec4 lampPosition; + int layer; +}; + +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 new file mode 100644 index 00000000000..dee020f19b4 --- /dev/null +++ b/source/blender/draw/engines/eevee/shaders/shadow_store_vert.glsl @@ -0,0 +1,8 @@ + +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/engines/eevee/shaders/shadow_vert.glsl b/source/blender/draw/engines/eevee/shaders/shadow_vert.glsl index ffb99f1b35c..323cf4d2a99 100644 --- a/source/blender/draw/engines/eevee/shaders/shadow_vert.glsl +++ b/source/blender/draw/engines/eevee/shaders/shadow_vert.glsl @@ -1,12 +1,21 @@ +layout(std140) uniform shadow_render_block { + mat4 ShadowMatrix[6]; + vec4 lampPosition; + int layer; +}; + uniform mat4 ShadowModelMatrix; in vec3 pos; out vec4 vPos; +out float lDist; + flat out int face; void main() { vPos = ShadowModelMatrix * vec4(pos, 1.0); + lDist = distance(lampPosition.xyz, vPos.xyz); face = gl_InstanceID; }
\ No newline at end of file |