Fix T77130: Visually broken/stepped wireframe in object mode (regression)

Create a new shader for the selection fix.

Differential Revision: https://developer.blender.org/D7873
This commit is contained in:
Clément Foucault 2020-05-29 11:14:10 +02:00
parent ff1040c6fe
commit 1d2b89304a
Notes: blender-bot 2023-02-14 06:00:44 +01:00
Referenced by issue #77172, EEVEE world doesn't update all viewports' object shaders
Referenced by issue #77173, UI warnings contrast worsened from 2.82 to 2.83
Referenced by issue #77130, Visually broken/stepped wireframe in object mode (regression)
5 changed files with 28 additions and 14 deletions

View File

@ -65,6 +65,7 @@ void OVERLAY_extra_cache_init(OVERLAY_Data *vedata)
OVERLAY_PassList *psl = vedata->psl;
OVERLAY_TextureList *txl = vedata->txl;
OVERLAY_PrivateData *pd = vedata->stl->pd;
const bool is_select = DRW_state_is_select();
DRWState state_blend = DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_ALPHA;
DRW_PASS_CREATE(psl->extra_blend_ps, state_blend | pd->clipping_state);
@ -108,7 +109,7 @@ void OVERLAY_extra_cache_init(OVERLAY_Data *vedata)
/* Sorted by shader to avoid state changes during render. */
{
format = formats->instance_extra;
sh = OVERLAY_shader_extra();
sh = OVERLAY_shader_extra(is_select);
grp = DRW_shgroup_create(sh, extra_ps);
DRW_shgroup_uniform_block_persistent(grp, "globalsBlock", G_draw.block_ubo);
@ -179,7 +180,7 @@ void OVERLAY_extra_cache_init(OVERLAY_Data *vedata)
cb->groundline = BUF_INSTANCE(grp, format, DRW_cache_groundline_get());
}
{
sh = OVERLAY_shader_extra_wire(false);
sh = OVERLAY_shader_extra_wire(false, is_select);
grp = DRW_shgroup_create(sh, extra_ps);
DRW_shgroup_uniform_block_persistent(grp, "globalsBlock", G_draw.block_ubo);
@ -188,7 +189,7 @@ void OVERLAY_extra_cache_init(OVERLAY_Data *vedata)
cb->extra_lines = BUF_LINE(grp, formats->wire_extra);
}
{
sh = OVERLAY_shader_extra_wire(true);
sh = OVERLAY_shader_extra_wire(true, is_select);
cb->extra_wire = grp = DRW_shgroup_create(sh, extra_ps);
DRW_shgroup_uniform_block_persistent(grp, "globalsBlock", G_draw.block_ubo);

View File

@ -589,9 +589,9 @@ GPUShader *OVERLAY_shader_edit_mesh_skin_root(void);
GPUShader *OVERLAY_shader_edit_mesh_vert(void);
GPUShader *OVERLAY_shader_edit_particle_strand(void);
GPUShader *OVERLAY_shader_edit_particle_point(void);
GPUShader *OVERLAY_shader_extra(void);
GPUShader *OVERLAY_shader_extra(bool is_select);
GPUShader *OVERLAY_shader_extra_groundline(void);
GPUShader *OVERLAY_shader_extra_wire(bool use_object);
GPUShader *OVERLAY_shader_extra_wire(bool use_object, bool is_select);
GPUShader *OVERLAY_shader_extra_loose_point(void);
GPUShader *OVERLAY_shader_extra_point(void);
GPUShader *OVERLAY_shader_facing(void);

View File

@ -164,8 +164,10 @@ typedef struct OVERLAY_Shaders {
GPUShader *edit_particle_strand;
GPUShader *edit_particle_point;
GPUShader *extra;
GPUShader *extra_select;
GPUShader *extra_groundline;
GPUShader *extra_wire[2];
GPUShader *extra_wire_select;
GPUShader *extra_point;
GPUShader *extra_lightprobe_grid;
GPUShader *extra_loose_point;
@ -797,23 +799,24 @@ GPUShader *OVERLAY_shader_edit_particle_point(void)
return sh_data->edit_particle_point;
}
GPUShader *OVERLAY_shader_extra(void)
GPUShader *OVERLAY_shader_extra(bool is_select)
{
const DRWContextState *draw_ctx = DRW_context_state_get();
const GPUShaderConfigData *sh_cfg = &GPU_shader_cfg_data[draw_ctx->sh_cfg];
OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg];
if (!sh_data->extra) {
sh_data->extra = GPU_shader_create_from_arrays({
GPUShader **sh = (is_select) ? &sh_data->extra_select : &sh_data->extra;
if (!*sh) {
*sh = GPU_shader_create_from_arrays({
.vert = (const char *[]){sh_cfg->lib,
datatoc_common_globals_lib_glsl,
datatoc_common_view_lib_glsl,
datatoc_extra_vert_glsl,
NULL},
.frag = (const char *[]){datatoc_common_view_lib_glsl, datatoc_extra_frag_glsl, NULL},
.defs = (const char *[]){sh_cfg->def, NULL},
.defs = (const char *[]){sh_cfg->def, (is_select) ? "#define SELECT_EDGES\n" : NULL, NULL},
});
}
return sh_data->extra;
return *sh;
}
GPUShader *OVERLAY_shader_extra_grid(void)
@ -855,12 +858,13 @@ GPUShader *OVERLAY_shader_extra_groundline(void)
return sh_data->extra_groundline;
}
GPUShader *OVERLAY_shader_extra_wire(bool use_object)
GPUShader *OVERLAY_shader_extra_wire(bool use_object, bool is_select)
{
const DRWContextState *draw_ctx = DRW_context_state_get();
const GPUShaderConfigData *sh_cfg = &GPU_shader_cfg_data[draw_ctx->sh_cfg];
OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg];
if (!sh_data->extra_wire[use_object]) {
GPUShader **sh = (is_select) ? &sh_data->extra_wire_select : &sh_data->extra_wire[use_object];
if (!*sh) {
char colorids[1024];
/* NOTE: define all ids we need here. */
BLI_snprintf(colorids,
@ -875,7 +879,7 @@ GPUShader *OVERLAY_shader_extra_wire(bool use_object)
TH_TRANSFORM,
TH_WIRE,
TH_CAMERA_PATH);
sh_data->extra_wire[use_object] = GPU_shader_create_from_arrays({
*sh = GPU_shader_create_from_arrays({
.vert = (const char *[]){sh_cfg->lib,
datatoc_common_globals_lib_glsl,
datatoc_common_view_lib_glsl,
@ -884,11 +888,12 @@ GPUShader *OVERLAY_shader_extra_wire(bool use_object)
.frag = (const char *[]){datatoc_common_view_lib_glsl, datatoc_extra_wire_frag_glsl, NULL},
.defs = (const char *[]){sh_cfg->def,
colorids,
(is_select) ? "#define SELECT_EDGES\n" : "",
(use_object) ? "#define OBJECT_WIRE \n" : NULL,
NULL},
});
}
return sh_data->extra_wire[use_object];
return *sh;
}
GPUShader *OVERLAY_shader_extra_loose_point(void)

View File

@ -221,10 +221,12 @@ void main()
/* Convert to screen position [0..sizeVp]. */
edgePos = edgeStart = ((gl_Position.xy / gl_Position.w) * 0.5 + 0.5) * sizeViewport.xy;
#ifdef SELECT_EDGES
/* HACK: to avoid loosing sub pixel object in selections, we add a bit of randomness to the
* wire to at least create one fragment that will pass the occlusion query. */
/* TODO(fclem) Limit this workaround to selection. It's not very noticeable but still... */
gl_Position.xy += sizeViewportInv.xy * gl_Position.w * ((gl_VertexID % 2 == 0) ? -1.0 : 1.0);
#endif
#ifdef USE_WORLD_CLIP_PLANES
world_clip_planes_calc_clip_distance(world_pos);

View File

@ -17,10 +17,12 @@ void main()
vec3 world_pos = point_object_to_world(pos);
gl_Position = point_world_to_ndc(world_pos);
#ifdef SELECT_EDGES
/* HACK: to avoid loosing sub pixel object in selections, we add a bit of randomness to the
* wire to at least create one fragment that will pass the occlusion query. */
/* TODO(fclem) Limit this workaround to selection. It's not very noticeable but still... */
gl_Position.xy += sizeViewportInv.xy * gl_Position.w * ((gl_VertexID % 2 == 0) ? -1.0 : 1.0);
#endif
stipple_coord = stipple_start = screen_position(gl_Position);
@ -39,6 +41,10 @@ void main()
}
#endif
#ifdef SELECT_EDGES
finalColor.a = 0.0; /* No Stipple */
#endif
#ifdef USE_WORLD_CLIP_PLANES
world_clip_planes_calc_clip_distance(world_pos);
#endif