Workbench: Shadow: Add shader variant for manifold case.
Totally Manifold objects only require a single increment/decrement of the stencil value. This result in less geometry generated and less overdraw.
This commit is contained in:
parent
0c9974c8cd
commit
975eac0b07
Notes:
blender-bot
2023-04-04 07:45:26 +02:00
Referenced by issue #54931, Workbench: Performance Shadows
|
@ -4,8 +4,6 @@
|
|||
#define USE_INVOC_EXT
|
||||
#endif
|
||||
|
||||
#define DOUBLE_MANIFOLD
|
||||
|
||||
#ifdef DOUBLE_MANIFOLD
|
||||
# ifdef USE_INVOC_EXT
|
||||
# define invoc_ct 4
|
||||
|
|
|
@ -4,8 +4,6 @@
|
|||
#define USE_INVOC_EXT
|
||||
#endif
|
||||
|
||||
#define DOUBLE_MANIFOLD
|
||||
|
||||
#ifdef DOUBLE_MANIFOLD
|
||||
# ifdef USE_INVOC_EXT
|
||||
# define invoc_ct 2
|
||||
|
|
|
@ -53,8 +53,11 @@ static struct {
|
|||
struct GPUShader *prepass_sh_cache[MAX_SHADERS];
|
||||
struct GPUShader *composite_sh_cache[MAX_SHADERS];
|
||||
struct GPUShader *shadow_fail_sh;
|
||||
struct GPUShader *shadow_fail_manifold_sh;
|
||||
struct GPUShader *shadow_pass_sh;
|
||||
struct GPUShader *shadow_pass_manifold_sh;
|
||||
struct GPUShader *shadow_caps_sh;
|
||||
struct GPUShader *shadow_caps_manifold_sh;
|
||||
|
||||
struct GPUTexture *object_id_tx; /* ref only, not alloced */
|
||||
struct GPUTexture *color_buffer_tx; /* ref only, not alloced */
|
||||
|
@ -181,11 +184,23 @@ void workbench_deferred_engine_init(WORKBENCH_Data *vedata)
|
|||
const char *shadow_frag = NULL;
|
||||
#endif
|
||||
e_data.shadow_pass_sh = DRW_shader_create(
|
||||
datatoc_workbench_shadow_vert_glsl,
|
||||
datatoc_workbench_shadow_geom_glsl,
|
||||
shadow_frag,
|
||||
"#define SHADOW_PASS\n"
|
||||
"#define DOUBLE_MANIFOLD\n");
|
||||
e_data.shadow_pass_manifold_sh = DRW_shader_create(
|
||||
datatoc_workbench_shadow_vert_glsl,
|
||||
datatoc_workbench_shadow_geom_glsl,
|
||||
shadow_frag,
|
||||
"#define SHADOW_PASS\n");
|
||||
e_data.shadow_fail_sh = DRW_shader_create(
|
||||
datatoc_workbench_shadow_vert_glsl,
|
||||
datatoc_workbench_shadow_geom_glsl,
|
||||
shadow_frag,
|
||||
"#define SHADOW_FAIL\n"
|
||||
"#define DOUBLE_MANIFOLD\n");
|
||||
e_data.shadow_fail_manifold_sh = DRW_shader_create(
|
||||
datatoc_workbench_shadow_vert_glsl,
|
||||
datatoc_workbench_shadow_geom_glsl,
|
||||
shadow_frag,
|
||||
|
@ -194,7 +209,13 @@ void workbench_deferred_engine_init(WORKBENCH_Data *vedata)
|
|||
datatoc_workbench_shadow_vert_glsl,
|
||||
datatoc_workbench_shadow_caps_geom_glsl,
|
||||
shadow_frag,
|
||||
NULL);
|
||||
"#define SHADOW_FAIL\n"
|
||||
"#define DOUBLE_MANIFOLD\n");
|
||||
e_data.shadow_caps_manifold_sh = DRW_shader_create(
|
||||
datatoc_workbench_shadow_vert_glsl,
|
||||
datatoc_workbench_shadow_caps_geom_glsl,
|
||||
shadow_frag,
|
||||
"#define SHADOW_FAIL\n");
|
||||
}
|
||||
|
||||
if (!stl->g_data) {
|
||||
|
@ -247,8 +268,11 @@ void workbench_deferred_engine_free()
|
|||
DRW_SHADER_FREE_SAFE(e_data.composite_sh_cache[index]);
|
||||
}
|
||||
DRW_SHADER_FREE_SAFE(e_data.shadow_pass_sh);
|
||||
DRW_SHADER_FREE_SAFE(e_data.shadow_pass_manifold_sh);
|
||||
DRW_SHADER_FREE_SAFE(e_data.shadow_fail_sh);
|
||||
DRW_SHADER_FREE_SAFE(e_data.shadow_fail_manifold_sh);
|
||||
DRW_SHADER_FREE_SAFE(e_data.shadow_caps_sh);
|
||||
DRW_SHADER_FREE_SAFE(e_data.shadow_caps_manifold_sh);
|
||||
}
|
||||
|
||||
static void workbench_composite_uniforms(WORKBENCH_PrivateData *wpd, DRWShadingGroup *grp)
|
||||
|
@ -308,32 +332,38 @@ void workbench_deferred_cache_init(WORKBENCH_Data *vedata)
|
|||
DRW_shgroup_uniform_float(grp, "shadowShift", &scene->display.shadow_shift, 1);
|
||||
DRW_shgroup_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL);
|
||||
|
||||
/* Stencil Shadow passes. */
|
||||
#ifdef DEBUG_SHADOW_VOLUME
|
||||
psl->shadow_depth_pass_pass = DRW_pass_create(
|
||||
"Shadow Debug Pass", DRW_STATE_DEPTH_LESS | DRW_STATE_WRITE_COLOR | DRW_STATE_ADDITIVE);
|
||||
grp = DRW_shgroup_create(e_data.shadow_pass_sh, psl->shadow_depth_pass_pass);
|
||||
psl->shadow_depth_fail_pass = DRW_pass_create(
|
||||
"Shadow Debug Fail", DRW_STATE_DEPTH_GREATER_EQUAL | DRW_STATE_WRITE_COLOR | DRW_STATE_ADDITIVE);
|
||||
grp = DRW_shgroup_create(e_data.shadow_fail_sh, psl->shadow_depth_fail_pass);
|
||||
psl->shadow_depth_fail_caps_pass = DRW_pass_create(
|
||||
"Shadow Depth Fail Caps", DRW_STATE_DEPTH_GREATER_EQUAL | DRW_STATE_WRITE_COLOR | DRW_STATE_ADDITIVE);
|
||||
grp = DRW_shgroup_create(e_data.shadow_caps_sh, psl->shadow_depth_fail_caps_pass);
|
||||
DRWState depth_pass_state = DRW_STATE_DEPTH_LESS | DRW_STATE_WRITE_COLOR | DRW_STATE_ADDITIVE;
|
||||
DRWState depth_fail_state = DRW_STATE_DEPTH_GREATER_EQUAL | DRW_STATE_WRITE_COLOR | DRW_STATE_ADDITIVE;
|
||||
#else
|
||||
psl->shadow_depth_pass_pass = DRW_pass_create(
|
||||
"Shadow Depth Pass", DRW_STATE_DEPTH_LESS | DRW_STATE_WRITE_STENCIL_SHADOW_PASS);
|
||||
DRWState depth_pass_state = DRW_STATE_DEPTH_LESS | DRW_STATE_WRITE_STENCIL_SHADOW_PASS;
|
||||
DRWState depth_fail_state = DRW_STATE_DEPTH_LESS | DRW_STATE_WRITE_STENCIL_SHADOW_FAIL;
|
||||
#endif
|
||||
psl->shadow_depth_pass_pass = DRW_pass_create("Shadow Pass", depth_pass_state);
|
||||
psl->shadow_depth_pass_mani_pass = DRW_pass_create("Shadow Pass Mani", depth_pass_state);
|
||||
psl->shadow_depth_fail_pass = DRW_pass_create("Shadow Fail", depth_fail_state);
|
||||
psl->shadow_depth_fail_mani_pass = DRW_pass_create("Shadow Fail Mani", depth_fail_state);
|
||||
psl->shadow_depth_fail_caps_pass = DRW_pass_create("Shadow Fail Caps", depth_fail_state);
|
||||
psl->shadow_depth_fail_caps_mani_pass = DRW_pass_create("Shadow Fail Caps Mani", depth_fail_state);
|
||||
|
||||
#ifndef DEBUG_SHADOW_VOLUME
|
||||
grp = DRW_shgroup_create(e_data.shadow_caps_sh, psl->shadow_depth_fail_caps_pass);
|
||||
DRW_shgroup_stencil_mask(grp, 0xFF);
|
||||
grp = DRW_shgroup_create(e_data.shadow_pass_sh, psl->shadow_depth_pass_pass);
|
||||
DRW_shgroup_stencil_mask(grp, 0xFF);
|
||||
psl->shadow_depth_fail_pass = DRW_pass_create(
|
||||
"Shadow Depth Fail", DRW_STATE_DEPTH_LESS | DRW_STATE_WRITE_STENCIL_SHADOW_FAIL);
|
||||
grp = DRW_shgroup_create(e_data.shadow_pass_manifold_sh, psl->shadow_depth_pass_mani_pass);
|
||||
DRW_shgroup_stencil_mask(grp, 0xFF);
|
||||
grp = DRW_shgroup_create(e_data.shadow_fail_sh, psl->shadow_depth_fail_pass);
|
||||
DRW_shgroup_stencil_mask(grp, 0xFF);
|
||||
psl->shadow_depth_fail_caps_pass = DRW_pass_create(
|
||||
"Shadow Depth Fail Caps", DRW_STATE_DEPTH_LESS | DRW_STATE_WRITE_STENCIL_SHADOW_FAIL);
|
||||
grp = DRW_shgroup_create(e_data.shadow_fail_manifold_sh, psl->shadow_depth_fail_mani_pass);
|
||||
DRW_shgroup_stencil_mask(grp, 0xFF);
|
||||
grp = DRW_shgroup_create(e_data.shadow_caps_sh, psl->shadow_depth_fail_caps_pass);
|
||||
DRW_shgroup_stencil_mask(grp, 0xFF);
|
||||
grp = DRW_shgroup_create(e_data.shadow_caps_manifold_sh, psl->shadow_depth_fail_caps_mani_pass);
|
||||
DRW_shgroup_stencil_mask(grp, 0xFF);
|
||||
|
||||
psl->composite_shadow_pass = DRW_pass_create(
|
||||
"Composite Shadow", DRW_STATE_WRITE_COLOR | DRW_STATE_STENCIL_NEQUAL);
|
||||
psl->composite_shadow_pass = DRW_pass_create("Composite Shadow", DRW_STATE_WRITE_COLOR | DRW_STATE_STENCIL_NEQUAL);
|
||||
grp = DRW_shgroup_create(wpd->composite_sh, psl->composite_shadow_pass);
|
||||
DRW_shgroup_stencil_mask(grp, 0x00);
|
||||
workbench_composite_uniforms(wpd, grp);
|
||||
|
@ -519,20 +549,38 @@ void workbench_deferred_solid_cache_populate(WORKBENCH_Data *vedata, Object *ob)
|
|||
mul_v3_mat3_m4v3(engine_object_data->shadow_dir, ob->imat, e_data.display.light_direction);
|
||||
|
||||
DRWShadingGroup *grp;
|
||||
if (!is_manifold) {
|
||||
grp = DRW_shgroup_create(e_data.shadow_pass_sh, psl->shadow_depth_pass_pass);
|
||||
/* TODO(fclem): only use shadow pass technique if camera is not in shadow. */
|
||||
const bool use_shadow_pass_technique = true;
|
||||
if (use_shadow_pass_technique) {
|
||||
if (is_manifold) {
|
||||
grp = DRW_shgroup_create(e_data.shadow_pass_manifold_sh, psl->shadow_depth_pass_mani_pass);
|
||||
}
|
||||
else {
|
||||
grp = DRW_shgroup_create(e_data.shadow_pass_sh, psl->shadow_depth_pass_pass);
|
||||
}
|
||||
DRW_shgroup_uniform_vec3(grp, "lightDirection", engine_object_data->shadow_dir, 1);
|
||||
DRW_shgroup_call_object_add(grp, geom_shadow, ob);
|
||||
}
|
||||
else {
|
||||
struct Gwn_Batch *geom_caps = DRW_cache_object_surface_get(ob);
|
||||
if (geom_caps) {
|
||||
grp = DRW_shgroup_create(e_data.shadow_caps_sh, psl->shadow_depth_fail_caps_pass);
|
||||
/* TODO(fclem): only use caps if they are in the view frustum. */
|
||||
const bool need_caps = true;
|
||||
if (need_caps) {
|
||||
if (is_manifold) {
|
||||
grp = DRW_shgroup_create(e_data.shadow_caps_manifold_sh, psl->shadow_depth_fail_caps_mani_pass);
|
||||
}
|
||||
else {
|
||||
grp = DRW_shgroup_create(e_data.shadow_caps_sh, psl->shadow_depth_fail_caps_pass);
|
||||
}
|
||||
DRW_shgroup_uniform_vec3(grp, "lightDirection", engine_object_data->shadow_dir, 1);
|
||||
DRW_shgroup_call_object_add(grp, geom_caps, ob);
|
||||
DRW_shgroup_call_object_add(grp, DRW_cache_object_surface_get(ob), ob);
|
||||
}
|
||||
|
||||
grp = DRW_shgroup_create(e_data.shadow_fail_sh, psl->shadow_depth_fail_pass);
|
||||
if (is_manifold) {
|
||||
grp = DRW_shgroup_create(e_data.shadow_fail_manifold_sh, psl->shadow_depth_fail_mani_pass);
|
||||
}
|
||||
else {
|
||||
grp = DRW_shgroup_create(e_data.shadow_fail_sh, psl->shadow_depth_fail_pass);
|
||||
}
|
||||
DRW_shgroup_uniform_vec3(grp, "lightDirection", engine_object_data->shadow_dir, 1);
|
||||
DRW_shgroup_call_object_add(grp, geom_shadow, ob);
|
||||
}
|
||||
|
@ -578,14 +626,16 @@ void workbench_deferred_draw_scene(WORKBENCH_Data *vedata)
|
|||
#ifdef DEBUG_SHADOW_VOLUME
|
||||
GPU_framebuffer_bind(fbl->composite_fb);
|
||||
DRW_draw_pass(psl->composite_pass);
|
||||
DRW_draw_pass(psl->shadow_depth_pass_pass);
|
||||
DRW_draw_pass(psl->shadow_depth_fail_pass);
|
||||
DRW_draw_pass(psl->shadow_depth_fail_caps_pass);
|
||||
#else
|
||||
GPU_framebuffer_bind(dfbl->depth_only_fb);
|
||||
#endif
|
||||
DRW_draw_pass(psl->shadow_depth_pass_pass);
|
||||
DRW_draw_pass(psl->shadow_depth_pass_mani_pass);
|
||||
DRW_draw_pass(psl->shadow_depth_fail_pass);
|
||||
DRW_draw_pass(psl->shadow_depth_fail_mani_pass);
|
||||
DRW_draw_pass(psl->shadow_depth_fail_caps_pass);
|
||||
DRW_draw_pass(psl->shadow_depth_fail_caps_mani_pass);
|
||||
#ifndef DEBUG_SHADOW_VOLUME
|
||||
GPU_framebuffer_bind(fbl->composite_fb);
|
||||
DRW_draw_pass(psl->composite_pass);
|
||||
DRW_draw_pass(psl->composite_shadow_pass);
|
||||
|
|
|
@ -70,8 +70,11 @@ typedef struct WORKBENCH_PassList {
|
|||
/* deferred rendering */
|
||||
struct DRWPass *prepass_pass;
|
||||
struct DRWPass *shadow_depth_pass_pass;
|
||||
struct DRWPass *shadow_depth_pass_mani_pass;
|
||||
struct DRWPass *shadow_depth_fail_pass;
|
||||
struct DRWPass *shadow_depth_fail_mani_pass;
|
||||
struct DRWPass *shadow_depth_fail_caps_pass;
|
||||
struct DRWPass *shadow_depth_fail_caps_mani_pass;
|
||||
struct DRWPass *composite_pass;
|
||||
struct DRWPass *composite_shadow_pass;
|
||||
|
||||
|
|
Loading…
Reference in New Issue