Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClément Foucault <foucault.clem@gmail.com>2019-02-07 18:30:08 +0300
committerClément Foucault <foucault.clem@gmail.com>2019-02-07 19:30:10 +0300
commita710af2b2571ce0564ee11cbcf5ebb35e6b09a3c (patch)
tree638bd6a10ebb819792cf08f09aa3c2c3620b4977 /source/blender/draw/modes
parent9b774dfa3b85b53774b9e0da2f1eba249d008a62 (diff)
Edit Mesh: Rework new implementation and use geometry shader to draw lines
This make it (theoriticaly) compatible with all supported hardware with consistent results. Also we now draw the lines with analytic anti-aliasing instead of relying on MSAA (which offers less benefits in our case). The remaining aliasing comes from edges cut in half by the mesh which is not rendered with MSAA. Hopefully this is not too much distracting and only happen if the face is almost parallel to the view.
Diffstat (limited to 'source/blender/draw/modes')
-rw-r--r--source/blender/draw/modes/edit_mesh_mode.c108
-rw-r--r--source/blender/draw/modes/shaders/edit_mesh_overlay_common_lib.glsl2
-rw-r--r--source/blender/draw/modes/shaders/edit_mesh_overlay_frag.glsl41
-rw-r--r--source/blender/draw/modes/shaders/edit_mesh_overlay_geom.glsl61
-rw-r--r--source/blender/draw/modes/shaders/edit_mesh_overlay_vert.glsl52
5 files changed, 112 insertions, 152 deletions
diff --git a/source/blender/draw/modes/edit_mesh_mode.c b/source/blender/draw/modes/edit_mesh_mode.c
index 0af90ad6f4b..d0b7e6484e3 100644
--- a/source/blender/draw/modes/edit_mesh_mode.c
+++ b/source/blender/draw/modes/edit_mesh_mode.c
@@ -104,7 +104,6 @@ typedef struct EDIT_MESH_Shaders {
GPUShader *overlay_vert;
GPUShader *overlay_edge;
GPUShader *overlay_edge_flat;
- GPUShader *overlay_edge_deco;
GPUShader *overlay_face;
GPUShader *overlay_facedot;
@@ -137,7 +136,6 @@ typedef struct EDIT_MESH_PrivateData {
DRWShadingGroup *vert_shgrp;
DRWShadingGroup *edge_shgrp;
- DRWShadingGroup *edge_deco_shgrp;
DRWShadingGroup *face_shgrp;
DRWShadingGroup *face_cage_shgrp;
DRWShadingGroup *facedot_shgrp;
@@ -150,7 +148,6 @@ typedef struct EDIT_MESH_PrivateData {
bool do_zbufclip;
bool do_faces;
bool do_edges;
- float edge_width_scale;
} EDIT_MESH_PrivateData; /* Transient data */
/* *********** FUNCTIONS *********** */
@@ -192,7 +189,12 @@ static void EDIT_MESH_engine_init(void *vedata)
});
char *lib = BLI_string_joinN(world_clip_lib_or_empty, datatoc_common_globals_lib_glsl, datatoc_edit_mesh_overlay_common_lib_glsl);
- const bool use_geom_shader = GPU_max_line_width() <= 2.0f;
+ /* Use geometry shader to draw edge wireframe. This ensure us
+ * the same result accross platforms and more flexibility. But
+ * we pay the cost of running a geometry shader.
+ * In the future we might consider using only the vertex shader
+ * and loading data manually with buffer textures. */
+ const bool use_geom_shader = true;
const char *geom_sh_code[] = {lib, datatoc_edit_mesh_overlay_geom_glsl, NULL};
if (!use_geom_shader) {
geom_sh_code[0] = NULL;
@@ -211,16 +213,10 @@ static void EDIT_MESH_engine_init(void *vedata)
});
sh_data->overlay_edge_flat = GPU_shader_create_from_arrays({
.vert = (const char *[]){lib, datatoc_edit_mesh_overlay_vert_glsl, NULL},
- .frag = (const char *[]){datatoc_gpu_shader_flat_color_frag_glsl, NULL},
+ .frag = (const char *[]){lib, datatoc_edit_mesh_overlay_frag_glsl, NULL},
.defs = (const char *[]){world_clip_def_or_empty, use_geom_def, "#define EDGE\n", "#define FLAT\n", NULL},
.geom = (use_geom_shader) ? geom_sh_code : NULL,
});
- sh_data->overlay_edge_deco = GPU_shader_create_from_arrays({
- .vert = (const char *[]){lib, datatoc_edit_mesh_overlay_vert_glsl, NULL},
- .frag = (const char *[]){datatoc_gpu_shader_flat_color_frag_glsl, NULL},
- .defs = (const char *[]){world_clip_def_or_empty, use_geom_def, "#define EDGE_DECORATION\n", "#define FLAT\n", NULL},
- .geom = (use_geom_shader) ? geom_sh_code : NULL,
- });
sh_data->overlay_vert = GPU_shader_create_from_arrays({
.vert = (const char *[]){lib, datatoc_edit_mesh_overlay_vert_glsl, NULL},
.frag = (const char *[]){datatoc_gpu_shader_point_varying_color_frag_glsl, NULL},
@@ -268,10 +264,10 @@ static void EDIT_MESH_engine_init(void *vedata)
}
static DRWPass *edit_mesh_create_overlay_pass(
- float *face_alpha, float *edge_width_scale, int *data_mask, bool do_edges, bool UNUSED(xray),
+ float *face_alpha, int *data_mask, bool do_edges, bool UNUSED(xray),
DRWState statemod,
DRWShadingGroup **r_face_shgrp, DRWShadingGroup **r_face_cage_shgrp, DRWShadingGroup **r_facedot_shgrp,
- DRWShadingGroup **r_edge_shgrp, DRWShadingGroup **r_edge_deco_shgrp, DRWShadingGroup **r_vert_shgrp)
+ DRWShadingGroup **r_edge_shgrp, DRWShadingGroup **r_vert_shgrp)
{
const DRWContextState *draw_ctx = DRW_context_state_get();
RegionView3D *rv3d = draw_ctx->rv3d;
@@ -280,6 +276,7 @@ static DRWPass *edit_mesh_create_overlay_pass(
EDIT_MESH_Shaders *sh_data = &e_data.sh_data[draw_ctx->shader_cfg];
const bool select_vert = (tsettings->selectmode & SCE_SELECT_VERTEX) != 0;
const bool select_face = (tsettings->selectmode & SCE_SELECT_FACE) != 0;
+ const bool select_edge = (tsettings->selectmode & SCE_SELECT_EDGE) != 0;
float winmat[4][4];
float viewdist = rv3d->dist;
DRW_viewport_matrix_get(winmat, DRW_MAT_WIN);
@@ -295,17 +292,15 @@ static DRWPass *edit_mesh_create_overlay_pass(
DRWShadingGroup *grp;
- /* TEST */
GPUShader *vert_sh = sh_data->overlay_vert;
GPUShader *edge_sh = (select_vert) ? sh_data->overlay_edge : sh_data->overlay_edge_flat;
GPUShader *face_sh = sh_data->overlay_face;
GPUShader *facedot_sh = sh_data->overlay_facedot;
- GPUShader *edge_deco_sh = sh_data->overlay_edge_deco;
+
/* Faces */
if (select_face) {
grp = *r_facedot_shgrp = DRW_shgroup_create(facedot_sh, pass);
DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
- DRW_shgroup_uniform_float(grp, "edgeScale", edge_width_scale, 1);
DRW_shgroup_state_enable(grp, DRW_STATE_WRITE_DEPTH);
if (rv3d->rflag & RV3D_CLIPPING) {
DRW_shgroup_world_clip_planes_from_rv3d(grp, rv3d);
@@ -315,7 +310,6 @@ static DRWPass *edit_mesh_create_overlay_pass(
grp = *r_face_shgrp = DRW_shgroup_create(face_sh, pass);
DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
DRW_shgroup_uniform_float(grp, "faceAlphaMod", face_alpha, 1);
- DRW_shgroup_uniform_float(grp, "edgeScale", edge_width_scale, 1);
DRW_shgroup_uniform_ivec4(grp, "dataMask", data_mask, 1);
DRW_shgroup_uniform_bool_copy(grp, "doEdges", do_edges);
DRW_shgroup_uniform_float_copy(grp, "ofs", 0.0f);
@@ -332,7 +326,6 @@ static DRWPass *edit_mesh_create_overlay_pass(
grp = *r_vert_shgrp = DRW_shgroup_create(vert_sh, pass);
DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
DRW_shgroup_uniform_vec2(grp, "viewportSize", DRW_viewport_size_get(), 1);
- DRW_shgroup_uniform_float(grp, "edgeScale", edge_width_scale, 1);
DRW_shgroup_uniform_float_copy(grp, "ofs", depth_ofs * 1.5f);
DRW_shgroup_state_enable(grp, DRW_STATE_OFFSET_NEGATIVE | DRW_STATE_WRITE_DEPTH);
DRW_shgroup_state_disable(grp, DRW_STATE_BLEND);
@@ -342,32 +335,19 @@ static DRWPass *edit_mesh_create_overlay_pass(
}
/* Edges */
- grp = *r_edge_deco_shgrp = DRW_shgroup_create(edge_deco_sh, pass);
- DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
- DRW_shgroup_uniform_vec2(grp, "viewportSize", DRW_viewport_size_get(), 1);
- DRW_shgroup_uniform_vec2(grp, "viewportSizeInv", DRW_viewport_invert_size_get(), 1);
- DRW_shgroup_uniform_ivec4(grp, "dataMask", data_mask, 1);
- DRW_shgroup_uniform_bool_copy(grp, "doEdges", do_edges);
- DRW_shgroup_uniform_float_copy(grp, "ofs", depth_ofs);
- DRW_shgroup_state_enable(grp, DRW_STATE_OFFSET_NEGATIVE);
- DRW_shgroup_state_enable(grp, DRW_STATE_BLEND);
- DRW_shgroup_state_enable(grp, DRW_STATE_WIRE_WIDE);
- /* To match blender loop structure. */
- DRW_shgroup_state_enable(grp, DRW_STATE_FIRST_VERTEX_CONVENTION);
- if (rv3d->rflag & RV3D_CLIPPING) {
- DRW_shgroup_world_clip_planes_from_rv3d(grp, rv3d);
- }
-
grp = *r_edge_shgrp = DRW_shgroup_create(edge_sh, pass);
DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
DRW_shgroup_uniform_vec2(grp, "viewportSize", DRW_viewport_size_get(), 1);
DRW_shgroup_uniform_vec2(grp, "viewportSizeInv", DRW_viewport_invert_size_get(), 1);
- DRW_shgroup_uniform_float(grp, "edgeScale", edge_width_scale, 1);
DRW_shgroup_uniform_ivec4(grp, "dataMask", data_mask, 1);
DRW_shgroup_uniform_bool_copy(grp, "doEdges", do_edges);
DRW_shgroup_uniform_float_copy(grp, "ofs", depth_ofs);
- DRW_shgroup_state_enable(grp, DRW_STATE_WRITE_DEPTH);
+ DRW_shgroup_uniform_float_copy(grp, "edgeScale", select_edge ? 1.75f : 1.0f);
DRW_shgroup_state_enable(grp, DRW_STATE_OFFSET_NEGATIVE);
+ /* TODO remove this when we draw only one line per edge. */
+ DRW_shgroup_state_enable(grp, DRW_STATE_WRITE_DEPTH);
+ DRW_shgroup_state_disable(grp, DRW_STATE_DEPTH_LESS_EQUAL);
+ DRW_shgroup_state_enable(grp, DRW_STATE_DEPTH_LESS);
/* To match blender loop structure. */
DRW_shgroup_state_enable(grp, DRW_STATE_FIRST_VERTEX_CONVENTION);
if (rv3d->rflag & RV3D_CLIPPING) {
@@ -406,9 +386,6 @@ static void EDIT_MESH_cache_init(void *vedata)
stl->g_data->do_zbufclip = ((v3d)->shading.flag & XRAY_FLAG(v3d)) != 0;
- /* Applies on top of the theme edge width, so edge-mode can have thick edges. */
- stl->g_data->edge_width_scale = (tsettings->selectmode & (SCE_SELECT_EDGE)) ? 1.75f : 1.0f;
-
stl->g_data->data_mask[0] = 0xFF; /* Face Flag */
stl->g_data->data_mask[1] = 0xFF; /* Edge Flag */
stl->g_data->data_mask[2] = 0xFF; /* Crease */
@@ -518,25 +495,23 @@ static void EDIT_MESH_cache_init(void *vedata)
if (!stl->g_data->do_zbufclip) {
psl->edit_face_overlay = edit_mesh_create_overlay_pass(
- &face_mod, &stl->g_data->edge_width_scale, stl->g_data->data_mask, stl->g_data->do_edges, false,
+ &face_mod, stl->g_data->data_mask, stl->g_data->do_edges, false,
DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_BLEND,
&stl->g_data->face_shgrp,
&stl->g_data->face_cage_shgrp,
&stl->g_data->facedot_shgrp,
&stl->g_data->edge_shgrp,
- &stl->g_data->edge_deco_shgrp,
&stl->g_data->vert_shgrp);
}
else {
/* We render all wires with depth and opaque to a new fbo and blend the result based on depth values */
psl->edit_face_occluded = edit_mesh_create_overlay_pass(
- &zero, &stl->g_data->edge_width_scale, stl->g_data->data_mask, stl->g_data->do_edges, true,
+ &zero, stl->g_data->data_mask, stl->g_data->do_edges, true,
DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_WRITE_DEPTH,
&stl->g_data->face_shgrp,
&stl->g_data->face_cage_shgrp,
&stl->g_data->facedot_shgrp,
&stl->g_data->edge_shgrp,
- &stl->g_data->edge_deco_shgrp,
&stl->g_data->vert_shgrp);
/* however we loose the front faces value (because we need the depth of occluded wires and
@@ -586,14 +561,12 @@ static void edit_mesh_add_ob_to_pass(
DRWShadingGroup *face_shgrp = (has_edit_mesh_cage) ? g_data->face_cage_shgrp : g_data->face_shgrp;
DRWShadingGroup *vert_shgrp = g_data->vert_shgrp;
DRWShadingGroup *edge_shgrp = g_data->edge_shgrp;
- DRWShadingGroup *edge_deco_shgrp = g_data->edge_deco_shgrp;
face_shgrp = (facefill_shgrp != NULL) ? facefill_shgrp : face_shgrp;
geom_tris = DRW_mesh_batch_cache_get_edit_triangles(ob->data);
geom_edges = DRW_mesh_batch_cache_get_edit_edges(ob->data);
DRW_shgroup_call_add(edge_shgrp, geom_edges, ob->obmat);
- DRW_shgroup_call_add(edge_deco_shgrp, geom_edges, ob->obmat);
DRW_shgroup_call_add(face_shgrp, geom_tris, ob->obmat);
if ((tsettings->selectmode & SCE_SELECT_VERTEX) != 0) {
@@ -733,27 +706,34 @@ static void EDIT_MESH_draw_scene(void *vedata)
const DRWContextState *draw_ctx = DRW_context_state_get();
View3D *v3d = draw_ctx->v3d;
- if (v3d->shading.type == OB_SOLID && (v3d->shading.flag & XRAY_FLAG(v3d)) == 0) {
- if (stl->g_data->ghost_ob == 1 && stl->g_data->edit_ob == 1) {
- /* In the case of single ghost object edit (common case for retopology):
- * we duplicate the depht+stencil buffer and clear all depth to 1.0f where
- * the stencil buffer is no 0x00. */
- const float *viewport_size = DRW_viewport_size_get();
- const int size[2] = {(int)viewport_size[0], (int)viewport_size[1]};
- struct GPUTexture *ghost_depth_tx = DRW_texture_pool_query_2D(size[0], size[1], GPU_DEPTH24_STENCIL8, &draw_engine_edit_mesh_type);
- GPU_framebuffer_ensure_config(&fbl->ghost_wire_fb, {
- GPU_ATTACHMENT_TEXTURE(ghost_depth_tx),
- GPU_ATTACHMENT_TEXTURE(dtxl->color),
- });
-
- GPU_framebuffer_blit(dfbl->depth_only_fb, 0, fbl->ghost_wire_fb, 0, GPU_DEPTH_BIT | GPU_STENCIL_BIT);
- GPU_framebuffer_bind(fbl->ghost_wire_fb);
-
- DRW_draw_pass(psl->ghost_clear_depth);
- }
+ if (v3d->shading.type == OB_SOLID && (v3d->shading.flag & XRAY_FLAG(v3d)) == 0 &&
+ stl->g_data->ghost_ob == 1 && stl->g_data->edit_ob == 1)
+ {
+ /* In the case of single ghost object edit (common case for retopology):
+ * we duplicate the depht+stencil buffer and clear all depth to 1.0f where
+ * the stencil buffer is no 0x00. */
+ const float *viewport_size = DRW_viewport_size_get();
+ const int size[2] = {(int)viewport_size[0], (int)viewport_size[1]};
+ struct GPUTexture *ghost_depth_tx = DRW_texture_pool_query_2D(size[0], size[1], GPU_DEPTH24_STENCIL8, &draw_engine_edit_mesh_type);
+ GPU_framebuffer_ensure_config(&fbl->ghost_wire_fb, {
+ GPU_ATTACHMENT_TEXTURE(ghost_depth_tx),
+ GPU_ATTACHMENT_TEXTURE(dtxl->color),
+ });
+
+ GPU_framebuffer_blit(dfbl->depth_only_fb, 0, fbl->ghost_wire_fb, 0, GPU_DEPTH_BIT | GPU_STENCIL_BIT);
+ GPU_framebuffer_bind(fbl->ghost_wire_fb);
+
+ DRW_draw_pass(psl->ghost_clear_depth);
+
+ DRW_draw_pass(psl->edit_face_overlay);
}
+ else {
+ // MULTISAMPLE_SYNC_ENABLE(dfbl, dtxl);
+
+ DRW_draw_pass(psl->edit_face_overlay);
- DRW_draw_pass(psl->edit_face_overlay);
+ // MULTISAMPLE_SYNC_DISABLE(dfbl, dtxl)
+ }
}
DRW_state_clip_planes_reset();
diff --git a/source/blender/draw/modes/shaders/edit_mesh_overlay_common_lib.glsl b/source/blender/draw/modes/shaders/edit_mesh_overlay_common_lib.glsl
index 682e77c347f..51b6e628deb 100644
--- a/source/blender/draw/modes/shaders/edit_mesh_overlay_common_lib.glsl
+++ b/source/blender/draw/modes/shaders/edit_mesh_overlay_common_lib.glsl
@@ -11,7 +11,7 @@ vec4 EDIT_MESH_edge_color_outer(int edge_flag, int face_flag, float crease, floa
color = ((edge_flag & EDGE_SEAM) != 0) ? colorEdgeSeam : color;
if ((face_flag & FACE_ACTIVE) != 0) {
- color = colorEditMeshActive;
+ color = vec4(colorEditMeshActive.rgb, 1.0);
}
return color;
}
diff --git a/source/blender/draw/modes/shaders/edit_mesh_overlay_frag.glsl b/source/blender/draw/modes/shaders/edit_mesh_overlay_frag.glsl
index bf41a0a43ae..d48c5158872 100644
--- a/source/blender/draw/modes/shaders/edit_mesh_overlay_frag.glsl
+++ b/source/blender/draw/modes/shaders/edit_mesh_overlay_frag.glsl
@@ -1,23 +1,36 @@
-#ifdef FLAT
-flat in vec4 finalColor;
-#else
-in vec4 finalColor;
-# ifdef EDGE
-flat in int selectOveride;
-# endif
-#endif
+#define M_1_SQRTPI 0.5641895835477563 /* 1/sqrt(pi) */
+
+/**
+ * We want to know how much a pixel is covered by a line.
+ * We replace the square pixel with acircle of the same area and try to find the intersection area.
+ * The area we search is the circular segment. https://en.wikipedia.org/wiki/Circular_segment
+ * The formula for the area uses inverse trig function and is quite complexe.
+ * Instead, we approximate it by using the smoothstep function and a 1.05 factor to the disc radius.
+ **/
+#define DISC_RADIUS (M_1_SQRTPI * 1.05)
+#define GRID_LINE_SMOOTH_START (0.5 - DISC_RADIUS)
+#define GRID_LINE_SMOOTH_END (0.5 + DISC_RADIUS)
+
+uniform float edgeScale;
+
+flat in vec4 finalColorOuter_f;
+in vec4 finalColor_f;
+in float edgeCoord_f;
out vec4 FragColor;
void main()
{
-#if defined(EDGE) && !defined(FLAT)
- vec4 prim_col = mix(colorEditMeshMiddle, colorEdgeSelect, finalColor.a);
- prim_col = (selectOveride != 0) ? prim_col : finalColor;
- prim_col.a = 1.0;
+ float dist = abs(edgeCoord_f) - max(sizeEdge * edgeScale - 0.5, 0.0);
+ float dist_outer = dist - max(sizeEdge * edgeScale, 1.0);
+#if 1
+ float mix_w = smoothstep(GRID_LINE_SMOOTH_START, GRID_LINE_SMOOTH_END, dist);
+ float mix_w_outer = smoothstep(GRID_LINE_SMOOTH_START, GRID_LINE_SMOOTH_END, dist_outer);
#else
-# define prim_col finalColor
+ float mix_w = step(0.5, dist);
+ float mix_w_outer = step(0.5, dist_outer);
#endif
- FragColor = prim_col;
+ FragColor = mix(finalColorOuter_f, finalColor_f, 1.0 - mix_w * finalColorOuter_f.a);
+ FragColor.a *= 1.0 - (finalColorOuter_f.a > 0.0 ? mix_w_outer : mix_w);
}
diff --git a/source/blender/draw/modes/shaders/edit_mesh_overlay_geom.glsl b/source/blender/draw/modes/shaders/edit_mesh_overlay_geom.glsl
index 1063f5dd59d..fcedbd759aa 100644
--- a/source/blender/draw/modes/shaders/edit_mesh_overlay_geom.glsl
+++ b/source/blender/draw/modes/shaders/edit_mesh_overlay_geom.glsl
@@ -4,33 +4,23 @@ layout(triangle_strip, max_vertices = 4) out;
uniform vec2 viewportSize;
uniform vec2 viewportSizeInv;
+uniform float edgeScale;
-in VertexData {
- vec4 finalColor;
-#if defined(EDGE) && !defined(FLAT)
- int selectOveride;
-#endif
-} v[];
+in vec4 finalColor[2];
+in vec4 finalColorOuter[2];
+in int selectOveride[2];
-#ifdef FLAT
-# define interp_col flat
-#else
-# define interp_col
-#endif
+flat out vec4 finalColorOuter_f;
+out vec4 finalColor_f;
+out float edgeCoord_f;
-interp_col out vec4 finalColor;
-#if defined(EDGE) && !defined(FLAT)
-flat out int selectOveride;
-#endif
-
-void do_vertex(const int i, vec2 offset)
+void do_vertex(const int i, float coord, vec2 offset)
{
- finalColor = v[i].finalColor;
-#if defined(EDGE) && !defined(FLAT)
- selectOveride = v[0].selectOveride;
-#endif
+ finalColor_f = (selectOveride[0] == 0) ? finalColor[i] : finalColor[0];
+ edgeCoord_f = coord;
gl_Position = gl_in[i].gl_Position;
- gl_Position.xy += offset * gl_Position.w;
+ /* Multiply offset by 2 because gl_Position range is [-1..1]. */
+ gl_Position.xy += offset * 2.0 * gl_Position.w;
EmitVertex();
}
@@ -41,25 +31,24 @@ void main()
ss_pos[1] = gl_in[1].gl_Position.xy / gl_in[1].gl_Position.w;
vec2 line = ss_pos[0] - ss_pos[1];
- line *= viewportSize;
-
- vec3 edge_ofs = sizeEdge * 2.0 * viewportSizeInv.xyy * vec3(1.0, 1.0, 0.0);
+ line = abs(line) * viewportSize;
-#ifdef EDGE_DECORATION
- edge_ofs *= 3.0;
+ finalColorOuter_f = finalColorOuter[0];
+ float half_size = sizeEdge * edgeScale;
+ /* Enlarge edge for flag display. */
+ half_size += (finalColorOuter_f.a > 0.0) ? max(sizeEdge * edgeScale, 1.0) : 0.0;
+ /* Add 1 px for AA */
+ half_size += 0.5;
- if (finalColor.a == 0.0) {
- return;
- }
-#endif
+ vec3 edge_ofs = half_size * viewportSizeInv.xyy * vec3(1.0, 1.0, 0.0);
- bool horizontal = abs(line.x) > abs(line.y);
+ bool horizontal = line.x > line.y;
edge_ofs = (horizontal) ? edge_ofs.zyz : edge_ofs.xzz;
- do_vertex(0, edge_ofs.xy);
- do_vertex(0, -edge_ofs.xy);
- do_vertex(1, edge_ofs.xy);
- do_vertex(1, -edge_ofs.xy);
+ do_vertex(0, half_size, edge_ofs.xy);
+ do_vertex(0, -half_size, -edge_ofs.xy);
+ do_vertex(1, half_size, edge_ofs.xy);
+ do_vertex(1, -half_size, -edge_ofs.xy);
EndPrimitive();
}
diff --git a/source/blender/draw/modes/shaders/edit_mesh_overlay_vert.glsl b/source/blender/draw/modes/shaders/edit_mesh_overlay_vert.glsl
index bc25ff17e74..378c5d2417a 100644
--- a/source/blender/draw/modes/shaders/edit_mesh_overlay_vert.glsl
+++ b/source/blender/draw/modes/shaders/edit_mesh_overlay_vert.glsl
@@ -17,32 +17,10 @@ in vec4 norAndFlag;
# define vnor norAndFlag.xyz
#endif
+out vec4 finalColor;
+out vec4 finalColorOuter;
#ifdef USE_GEOM_SHADER
-# define qual_col
-# define qual_sel
-#else
-# ifdef FLAT
-# define qual_col flat out
-# else
-# define qual_col out
-# endif
-# define qual_sel flat out
-#endif
-
-#ifdef USE_GEOM_SHADER
-out VertexData {
-#endif
-
-qual_col vec4 finalColor;
-#if defined(EDGE) && !defined(FLAT)
-qual_sel int selectOveride;
-#endif
-
-#ifdef USE_GEOM_SHADER
-} v;
-# define v(a) v.a
-#else
-# define v(a) a
+out int selectOveride;
#endif
void main()
@@ -60,7 +38,7 @@ void main()
ivec4 m_data = data & dataMask;
#if defined(VERT)
- v(finalColor) = EDIT_MESH_vertex_color(m_data.y);
+ finalColor = EDIT_MESH_vertex_color(m_data.y);
gl_PointSize = sizeVertex * 2.0;
gl_Position.z -= 3e-5 * ((ProjectionMatrix[3][3] == 0.0) ? 1.0 : 0.0);
/* Make selected and active vertex always on top. */
@@ -73,23 +51,23 @@ void main()
#elif defined(EDGE)
# ifdef FLAT
- v(finalColor) = EDIT_MESH_edge_color_inner(m_data.y);
+ finalColor = EDIT_MESH_edge_color_inner(m_data.y);
+ selectOveride = 1;
# else
- v(finalColor) = EDIT_MESH_edge_vertex_color(m_data.y);
- v(selectOveride) = (m_data.y & EDGE_SELECTED);
+ finalColor = EDIT_MESH_edge_vertex_color(m_data.y);
+ selectOveride = (m_data.y & EDGE_SELECTED);
# endif
-#elif defined(EDGE_DECORATION)
float crease = float(m_data.z) / 255.0;
float bweight = float(m_data.w) / 255.0;
- v(finalColor) = EDIT_MESH_edge_color_outer(m_data.y, m_data.x, crease, bweight);
+ finalColorOuter = EDIT_MESH_edge_color_outer(m_data.y, m_data.x, crease, bweight);
#elif defined(FACE)
- v(finalColor) = EDIT_MESH_face_color(m_data.x);
- v(finalColor).a *= faceAlphaMod;
+ finalColor = EDIT_MESH_face_color(m_data.x);
+ finalColor.a *= faceAlphaMod;
#elif defined(FACEDOT)
- v(finalColor) = EDIT_MESH_facedot_color(norAndFlag.w);
+ finalColor = EDIT_MESH_facedot_color(norAndFlag.w);
/* Bias Facedot Z position in clipspace. */
gl_Position.z -= 0.00035;
gl_PointSize = sizeFaceDot;
@@ -106,12 +84,12 @@ void main()
float facing = dot(view_vec, view_normal);
facing = 1.0 - abs(facing) * 0.3;
- v(finalColor) = mix(colorEditMeshMiddle, v(finalColor), facing);
- v(finalColor).a = 1.0;
+ finalColor = mix(colorEditMeshMiddle, finalColor, facing);
+ finalColor.a = 1.0;
# if defined(EDGE) && !defined(FLAT)
/* Hack to blend color in pixel shader in case of overide. */
- v(finalColor).a = facing;
+ finalColor.a = facing;
# endif
#endif