Fix workbench object outline ignoring clipping
Workbench forward engine wasn't recompiling shaders when clipping changed, use GPUShaderConfigData when creating shaders.
This commit is contained in:
parent
0093ad643a
commit
7454fa927b
Notes:
blender-bot
2023-04-14 09:18:04 +02:00
Referenced by issue #62873, GPUShader: compile error (when clipping in viewport) Referenced by issue #62792, Edit mode, Clipping region, Visuals bug and editing vertices remain slow like when geometry is not hidden Referenced by issue #62563, Hair Dynamics: cannot generate a valid particle cache
|
@ -53,8 +53,13 @@
|
|||
# include "draw_debug.h"
|
||||
#endif
|
||||
|
||||
static struct {
|
||||
typedef struct WORKBENCH_DEFERRED_Shaders {
|
||||
struct GPUShader *prepass_sh_cache[MAX_PREPASS_SHADERS];
|
||||
} WORKBENCH_DEFERRED_Shaders;
|
||||
|
||||
static struct {
|
||||
WORKBENCH_DEFERRED_Shaders sh_data[GPU_SHADER_CFG_LEN];
|
||||
|
||||
struct GPUShader *composite_sh_cache[MAX_COMPOSITE_SHADERS];
|
||||
struct GPUShader *cavity_sh[MAX_CAVITY_SHADERS];
|
||||
struct GPUShader *background_sh[2];
|
||||
|
@ -84,7 +89,7 @@ static struct {
|
|||
struct GPUUniformBuffer *sampling_ubo;
|
||||
struct GPUTexture *jitter_tx;
|
||||
int cached_sample_num;
|
||||
} e_data = {{NULL}};
|
||||
} e_data = {{{{NULL}}}};
|
||||
|
||||
/* Shaders */
|
||||
extern char datatoc_common_hair_lib_glsl[];
|
||||
|
@ -220,21 +225,26 @@ static GPUShader *workbench_cavity_shader_get(bool cavity, bool curvature)
|
|||
return *sh;
|
||||
}
|
||||
|
||||
static GPUShader *ensure_deferred_prepass_shader(WORKBENCH_PrivateData *wpd, bool use_textures, bool is_hair)
|
||||
static GPUShader *ensure_deferred_prepass_shader(
|
||||
WORKBENCH_PrivateData *wpd, bool use_textures, bool is_hair, eGPUShaderConfig sh_cfg)
|
||||
{
|
||||
WORKBENCH_DEFERRED_Shaders *sh_data = &e_data.sh_data[sh_cfg];
|
||||
int index = workbench_material_get_prepass_shader_index(wpd, use_textures, is_hair);
|
||||
if (e_data.prepass_sh_cache[index] == NULL) {
|
||||
if (sh_data->prepass_sh_cache[index] == NULL) {
|
||||
const GPUShaderConfigData *sh_cfg_data = &GPU_shader_cfg_data[sh_cfg];
|
||||
char *defines = workbench_material_build_defines(wpd, use_textures, is_hair);
|
||||
char *prepass_vert = workbench_build_prepass_vert(is_hair);
|
||||
char *prepass_frag = workbench_build_prepass_frag();
|
||||
e_data.prepass_sh_cache[index] = DRW_shader_create(
|
||||
prepass_vert, NULL,
|
||||
prepass_frag, defines);
|
||||
sh_data->prepass_sh_cache[index] = GPU_shader_create_from_arrays({
|
||||
.vert = (const char *[]){sh_cfg_data->lib, prepass_vert, NULL},
|
||||
.frag = (const char *[]){prepass_frag, NULL},
|
||||
.defs = (const char *[]){sh_cfg_data->def, defines, NULL},
|
||||
});
|
||||
MEM_freeN(prepass_vert);
|
||||
MEM_freeN(prepass_frag);
|
||||
MEM_freeN(defines);
|
||||
}
|
||||
return e_data.prepass_sh_cache[index];
|
||||
return sh_data->prepass_sh_cache[index];
|
||||
}
|
||||
|
||||
static GPUShader *ensure_deferred_composite_shader(WORKBENCH_PrivateData *wpd)
|
||||
|
@ -267,12 +277,13 @@ static GPUShader *ensure_background_shader(WORKBENCH_PrivateData *wpd)
|
|||
return e_data.background_sh[index];
|
||||
}
|
||||
|
||||
static void select_deferred_shaders(WORKBENCH_PrivateData *wpd)
|
||||
static void select_deferred_shaders(WORKBENCH_PrivateData *wpd, eGPUShaderConfig sh_cfg)
|
||||
{
|
||||
wpd->prepass_solid_sh = ensure_deferred_prepass_shader(wpd, false, false);
|
||||
wpd->prepass_solid_hair_sh = ensure_deferred_prepass_shader(wpd, false, true);
|
||||
wpd->prepass_texture_sh = ensure_deferred_prepass_shader(wpd, true, false);
|
||||
wpd->prepass_texture_hair_sh = ensure_deferred_prepass_shader(wpd, true, true);
|
||||
wpd->prepass_solid_sh
|
||||
= ensure_deferred_prepass_shader(wpd, false, false, sh_cfg);
|
||||
wpd->prepass_solid_hair_sh = ensure_deferred_prepass_shader(wpd, false, true, sh_cfg);
|
||||
wpd->prepass_texture_sh = ensure_deferred_prepass_shader(wpd, true, false, sh_cfg);
|
||||
wpd->prepass_texture_hair_sh = ensure_deferred_prepass_shader(wpd, true, true, sh_cfg);
|
||||
wpd->composite_sh = ensure_deferred_composite_shader(wpd);
|
||||
wpd->background_sh = ensure_background_shader(wpd);
|
||||
}
|
||||
|
@ -375,7 +386,8 @@ void workbench_deferred_engine_init(WORKBENCH_Data *vedata)
|
|||
}
|
||||
|
||||
if (!e_data.next_object_id) {
|
||||
memset(e_data.prepass_sh_cache, 0, sizeof(e_data.prepass_sh_cache));
|
||||
WORKBENCH_DEFERRED_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg];
|
||||
memset(sh_data->prepass_sh_cache, 0, sizeof(sh_data->prepass_sh_cache));
|
||||
memset(e_data.composite_sh_cache, 0, sizeof(e_data.composite_sh_cache));
|
||||
e_data.next_object_id = 1;
|
||||
#ifdef DEBUG_SHADOW_VOLUME
|
||||
|
@ -596,8 +608,11 @@ static void workbench_setup_ghost_framebuffer(WORKBENCH_FramebufferList *fbl)
|
|||
|
||||
void workbench_deferred_engine_free(void)
|
||||
{
|
||||
for (int index = 0; index < MAX_PREPASS_SHADERS; index++) {
|
||||
DRW_SHADER_FREE_SAFE(e_data.prepass_sh_cache[index]);
|
||||
for (int sh_data_index = 0; sh_data_index < ARRAY_SIZE(e_data.sh_data); sh_data_index++) {
|
||||
WORKBENCH_DEFERRED_Shaders *sh_data = &e_data.sh_data[sh_data_index];
|
||||
for (int index = 0; index < MAX_PREPASS_SHADERS; index++) {
|
||||
DRW_SHADER_FREE_SAFE(sh_data->prepass_sh_cache[index]);
|
||||
}
|
||||
}
|
||||
for (int index = 0; index < MAX_COMPOSITE_SHADERS; index++) {
|
||||
DRW_SHADER_FREE_SAFE(e_data.composite_sh_cache[index]);
|
||||
|
@ -668,7 +683,7 @@ void workbench_deferred_cache_init(WORKBENCH_Data *vedata)
|
|||
|
||||
workbench_volume_cache_init(vedata);
|
||||
|
||||
select_deferred_shaders(wpd);
|
||||
select_deferred_shaders(wpd, draw_ctx->sh_cfg);
|
||||
|
||||
/* Background Pass */
|
||||
{
|
||||
|
|
|
@ -85,20 +85,13 @@ extern char datatoc_workbench_world_light_lib_glsl[];
|
|||
/* static functions */
|
||||
static char *workbench_build_forward_vert(bool is_hair)
|
||||
{
|
||||
char *str = NULL;
|
||||
if (!is_hair) {
|
||||
return BLI_string_joinN(
|
||||
datatoc_gpu_shader_cfg_world_clip_lib_glsl,
|
||||
datatoc_workbench_prepass_vert_glsl);
|
||||
}
|
||||
|
||||
DynStr *ds = BLI_dynstr_new();
|
||||
|
||||
BLI_dynstr_append(ds, datatoc_common_hair_lib_glsl);
|
||||
BLI_dynstr_append(ds, datatoc_gpu_shader_cfg_world_clip_lib_glsl);
|
||||
if (is_hair) {
|
||||
BLI_dynstr_append(ds, datatoc_common_hair_lib_glsl);
|
||||
}
|
||||
BLI_dynstr_append(ds, datatoc_workbench_prepass_vert_glsl);
|
||||
|
||||
str = BLI_dynstr_get_cstring(ds);
|
||||
char *str = BLI_dynstr_get_cstring(ds);
|
||||
BLI_dynstr_free(ds);
|
||||
return str;
|
||||
}
|
||||
|
@ -221,12 +214,15 @@ static GPUShader *ensure_forward_accum_shaders(
|
|||
WORKBENCH_FORWARD_Shaders *sh_data = &e_data.sh_data[sh_cfg];
|
||||
int index = workbench_material_get_accum_shader_index(wpd, use_textures, is_hair);
|
||||
if (sh_data->transparent_accum_sh_cache[index] == NULL) {
|
||||
const GPUShaderConfigData *sh_cfg_data = &GPU_shader_cfg_data[sh_cfg];
|
||||
char *defines = workbench_material_build_defines(wpd, use_textures, is_hair);
|
||||
char *transparent_accum_vert = workbench_build_forward_vert(is_hair);
|
||||
char *transparent_accum_frag = workbench_build_forward_transparent_accum_frag();
|
||||
sh_data->transparent_accum_sh_cache[index] = DRW_shader_create(
|
||||
transparent_accum_vert, NULL,
|
||||
transparent_accum_frag, defines);
|
||||
sh_data->transparent_accum_sh_cache[index] = GPU_shader_create_from_arrays({
|
||||
.vert = (const char *[]){sh_cfg_data->lib, transparent_accum_vert, NULL},
|
||||
.frag = (const char *[]){transparent_accum_frag, NULL},
|
||||
.defs = (const char *[]){sh_cfg_data->def, defines, NULL},
|
||||
});
|
||||
MEM_freeN(transparent_accum_vert);
|
||||
MEM_freeN(transparent_accum_frag);
|
||||
MEM_freeN(defines);
|
||||
|
@ -261,21 +257,28 @@ void workbench_forward_outline_shaders_ensure(WORKBENCH_PrivateData *wpd, eGPUSh
|
|||
WORKBENCH_FORWARD_Shaders *sh_data = &e_data.sh_data[sh_cfg];
|
||||
|
||||
if (sh_data->object_outline_sh == NULL) {
|
||||
const GPUShaderConfigData *sh_cfg_data = &GPU_shader_cfg_data[sh_cfg];
|
||||
char *defines = workbench_material_build_defines(wpd, false, false);
|
||||
char *defines_texture = workbench_material_build_defines(wpd, true, false);
|
||||
char *defines_hair = workbench_material_build_defines(wpd, false, true);
|
||||
char *forward_vert = workbench_build_forward_vert(false);
|
||||
char *forward_hair_vert = workbench_build_forward_vert(true);
|
||||
|
||||
sh_data->object_outline_sh = DRW_shader_create(
|
||||
forward_vert, NULL,
|
||||
datatoc_workbench_forward_depth_frag_glsl, defines);
|
||||
sh_data->object_outline_texture_sh = DRW_shader_create(
|
||||
forward_vert, NULL,
|
||||
datatoc_workbench_forward_depth_frag_glsl, defines_texture);
|
||||
sh_data->object_outline_hair_sh = DRW_shader_create(
|
||||
forward_hair_vert, NULL,
|
||||
datatoc_workbench_forward_depth_frag_glsl, defines_hair);
|
||||
sh_data->object_outline_sh = GPU_shader_create_from_arrays({
|
||||
.vert = (const char *[]){sh_cfg_data->lib, forward_vert, NULL},
|
||||
.frag = (const char *[]){datatoc_workbench_forward_depth_frag_glsl, NULL},
|
||||
.defs = (const char *[]){sh_cfg_data->def, defines, NULL},
|
||||
});
|
||||
sh_data->object_outline_texture_sh = GPU_shader_create_from_arrays({
|
||||
.vert = (const char *[]){sh_cfg_data->lib, forward_vert, NULL},
|
||||
.frag = (const char *[]){datatoc_workbench_forward_depth_frag_glsl, NULL},
|
||||
.defs = (const char *[]){sh_cfg_data->def, defines_texture, NULL},
|
||||
});
|
||||
sh_data->object_outline_hair_sh = GPU_shader_create_from_arrays({
|
||||
.vert = (const char *[]){sh_cfg_data->lib, forward_hair_vert, NULL},
|
||||
.frag = (const char *[]){datatoc_workbench_forward_depth_frag_glsl, NULL},
|
||||
.defs = (const char *[]){sh_cfg_data->def, defines_hair, NULL},
|
||||
});
|
||||
|
||||
MEM_freeN(forward_hair_vert);
|
||||
MEM_freeN(forward_vert);
|
||||
|
|
|
@ -130,9 +130,6 @@ char *workbench_material_build_defines(WORKBENCH_PrivateData *wpd, bool use_text
|
|||
if (is_hair) {
|
||||
BLI_dynstr_appendf(ds, "#define HAIR_SHADER\n");
|
||||
}
|
||||
if (WORLD_CLIPPING_ENABLED(wpd)) {
|
||||
BLI_dynstr_appendf(ds, "#define USE_WORLD_CLIP_PLANES\n");
|
||||
}
|
||||
|
||||
str = BLI_dynstr_get_cstring(ds);
|
||||
BLI_dynstr_free(ds);
|
||||
|
@ -192,7 +189,6 @@ int workbench_material_get_prepass_shader_index(
|
|||
SET_FLAG_FROM_TEST(index, NORMAL_VIEWPORT_PASS_ENABLED(wpd), 1 << 3);
|
||||
SET_FLAG_FROM_TEST(index, MATCAP_ENABLED(wpd), 1 << 4);
|
||||
SET_FLAG_FROM_TEST(index, use_textures, 1 << 5);
|
||||
SET_FLAG_FROM_TEST(index, WORLD_CLIPPING_ENABLED(wpd), 1 << 6);
|
||||
BLI_assert(index < MAX_PREPASS_SHADERS);
|
||||
return index;
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
#define WORKBENCH_ENGINE "BLENDER_WORKBENCH"
|
||||
#define M_GOLDEN_RATION_CONJUGATE 0.618033988749895
|
||||
#define MAX_COMPOSITE_SHADERS (1 << 6)
|
||||
#define MAX_PREPASS_SHADERS (1 << 7)
|
||||
#define MAX_PREPASS_SHADERS (1 << 6)
|
||||
#define MAX_ACCUM_SHADERS (1 << 5)
|
||||
#define MAX_CAVITY_SHADERS (1 << 3)
|
||||
|
||||
|
|
Loading…
Reference in New Issue