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-13 01:22:36 +0300
committerClément Foucault <foucault.clem@gmail.com>2019-02-18 16:17:57 +0300
commite49d9555418d571f0585bf9a33aed90008e72e2c (patch)
treea046b2f2e0431e3939fcaace23c6b122ccccd96a /source/blender/draw/modes
parent253ff57617a90537b334449ad992c7ef13f997ea (diff)
Wireframe: Refactor to use GL_LINES instead of triangles with alpha blend
This gets rid of the progressive fading of the edges as it does not work with depth perception (sorting problem with alpha blending).
Diffstat (limited to 'source/blender/draw/modes')
-rw-r--r--source/blender/draw/modes/overlay_mode.c87
-rw-r--r--source/blender/draw/modes/shaders/overlay_face_wireframe_frag.glsl38
-rw-r--r--source/blender/draw/modes/shaders/overlay_face_wireframe_vert.glsl41
3 files changed, 50 insertions, 116 deletions
diff --git a/source/blender/draw/modes/overlay_mode.c b/source/blender/draw/modes/overlay_mode.c
index 550dfe0be7a..9ff8e2b30f1 100644
--- a/source/blender/draw/modes/overlay_mode.c
+++ b/source/blender/draw/modes/overlay_mode.c
@@ -55,7 +55,7 @@ typedef struct OVERLAY_PrivateData {
DRWShadingGroup *flat_wires_shgrp;
DRWShadingGroup *sculpt_wires_shgrp;
View3DOverlay overlay;
- float wire_step_param[2];
+ float wire_step_param;
bool ghost_stencil_test;
bool show_overlays;
} OVERLAY_PrivateData; /* Transient data */
@@ -127,9 +127,8 @@ static void overlay_engine_init(void *vedata)
});
sh_data->face_wireframe_sculpt = GPU_shader_create_from_arrays({
.vert = (const char *[]){sh_cfg_data->lib, datatoc_overlay_face_wireframe_vert_glsl, NULL},
- .geom = (const char *[]){sh_cfg_data->lib, datatoc_overlay_face_wireframe_geom_glsl, NULL},
.frag = (const char *[]){datatoc_overlay_face_wireframe_frag_glsl, NULL},
- .defs = (const char *[]){sh_cfg_data->def, "#define USE_SCULPT\n", NULL},
+ .defs = (const char *[]){sh_cfg_data->def, NULL},
});
}
}
@@ -179,7 +178,7 @@ static void overlay_cache_init(void *vedata)
{
/* Wireframe */
- DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_BLEND | DRW_STATE_FIRST_VERTEX_CONVENTION;
+ DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_FIRST_VERTEX_CONVENTION | DRW_STATE_OFFSET_NEGATIVE;
float wire_size = max_ff(0.0f, U.pixelsize - 1.0f) * 0.5f;
const bool use_select = (DRW_state_is_select() || DRW_state_is_depth());
@@ -200,7 +199,7 @@ static void overlay_cache_init(void *vedata)
}
g_data->face_wires_shgrp = DRW_shgroup_create(face_wires_sh, psl->face_wireframe_pass);
- DRW_shgroup_uniform_vec2(g_data->face_wires_shgrp, "wireStepParam", g_data->wire_step_param, 1);
+ DRW_shgroup_uniform_float(g_data->face_wires_shgrp, "wireStepParam", &g_data->wire_step_param, 1);
if (rv3d->rflag & RV3D_CLIPPING) {
DRW_shgroup_world_clip_planes_from_rv3d(g_data->face_wires_shgrp, rv3d);
}
@@ -210,14 +209,7 @@ static void overlay_cache_init(void *vedata)
DRW_shgroup_uniform_float_copy(g_data->face_wires_shgrp, "wireSize", wire_size);
}
- /* Control aspect of the falloff. */
- const float sharpness = 4.0f;
- /* Scale and bias: Adjust with wiredata encoding. (see mesh_batch_cache_create_edges_wireframe_data) */
- const float decompress = (0xFF / (float)(0xFF - 0x20));
- g_data->wire_step_param[0] = -sharpness * decompress;
- g_data->wire_step_param[1] = decompress + sharpness * stl->g_data->overlay.wireframe_threshold;
-
-
+ g_data->wire_step_param = stl->g_data->overlay.wireframe_threshold - 254.0f / 255.0f;
}
}
@@ -227,7 +219,6 @@ static void overlay_cache_populate(void *vedata, Object *ob)
OVERLAY_StorageList *stl = data->stl;
OVERLAY_PrivateData *pd = stl->g_data;
const DRWContextState *draw_ctx = DRW_context_state_get();
- RegionView3D *rv3d = draw_ctx->rv3d;
View3D *v3d = draw_ctx->v3d;
if ((!pd->show_overlays) ||
@@ -266,14 +257,14 @@ static void overlay_cache_populate(void *vedata, Object *ob)
{
const bool is_active = (ob == draw_ctx->obact);
const bool is_sculpt_mode = is_active && (draw_ctx->object_mode & OB_MODE_SCULPT) != 0;
- const bool all_wires = (pd->overlay.wireframe_threshold == 1.0f) ||
- (ob->dtx & OB_DRAW_ALL_EDGES);
+ const bool all_wires = (ob->dtx & OB_DRAW_ALL_EDGES);
const bool is_wire = (ob->dt < OB_SOLID);
const int stencil_mask = (ob->dtx & OB_DRAWXRAY) ? 0x00 : 0xFF;
DRWShadingGroup *shgrp = NULL;
const float *rim_col = NULL;
const float *wire_col = NULL;
+
if (UNLIKELY(ob->base_flag & BASE_FROM_SET)) {
rim_col = G_draw.block.colorDupli;
wire_col = G_draw.block.colorDupli;
@@ -312,47 +303,29 @@ static void overlay_cache_populate(void *vedata, Object *ob)
}
BLI_assert(rim_col && wire_col);
- /* This fixes only the biggest case which is a plane in ortho view. */
- int flat_axis = 0;
- bool is_flat_object_viewed_from_side = (
- (rv3d->persp == RV3D_ORTHO) &&
- DRW_object_is_flat(ob, &flat_axis) &&
- DRW_object_axis_orthogonal_to_view(ob, flat_axis));
-
- if (is_flat_object_viewed_from_side && !is_sculpt_mode) {
- /* Avoid losing flat objects when in ortho views (see T56549) */
- struct GPUBatch *geom = DRW_cache_object_all_edges_get(ob);
- if (geom) {
- shgrp = pd->flat_wires_shgrp;
- shgrp = DRW_shgroup_create_sub(shgrp);
+ struct GPUBatch *geom;
+ geom = DRW_cache_object_face_wireframe_get(ob);
+
+ if (geom || is_sculpt_mode) {
+ shgrp = (is_sculpt_mode) ? pd->sculpt_wires_shgrp : pd->face_wires_shgrp;
+ shgrp = DRW_shgroup_create_sub(shgrp);
+
+ static float all_wires_param = 10.0f;
+ DRW_shgroup_uniform_vec2(
+ shgrp, "wireStepParam", (all_wires) ?
+ &all_wires_param : &pd->wire_step_param, 1);
+
+ if (!(DRW_state_is_select() || DRW_state_is_depth())) {
DRW_shgroup_stencil_mask(shgrp, stencil_mask);
- DRW_shgroup_call_object_add(shgrp, geom, ob);
- DRW_shgroup_uniform_vec4(shgrp, "color", rim_col, 1);
+ DRW_shgroup_uniform_vec3(shgrp, "wireColor", wire_col, 1);
+ DRW_shgroup_uniform_vec3(shgrp, "rimColor", rim_col, 1);
}
- }
- else {
- struct GPUBatch *geom = DRW_cache_object_face_wireframe_get(ob);
- if (geom || is_sculpt_mode) {
- shgrp = (is_sculpt_mode) ? pd->sculpt_wires_shgrp : pd->face_wires_shgrp;
- shgrp = DRW_shgroup_create_sub(shgrp);
-
- static float all_wires_params[2] = {0.0f, 10.0f}; /* Parameters for all wires */
- DRW_shgroup_uniform_vec2(
- shgrp, "wireStepParam", (all_wires) ?
- all_wires_params : pd->wire_step_param, 1);
-
- if (!(DRW_state_is_select() || DRW_state_is_depth())) {
- DRW_shgroup_stencil_mask(shgrp, stencil_mask);
- DRW_shgroup_uniform_vec3(shgrp, "wireColor", wire_col, 1);
- DRW_shgroup_uniform_vec3(shgrp, "rimColor", rim_col, 1);
- }
- if (is_sculpt_mode) {
- DRW_shgroup_call_sculpt_add(shgrp, ob, ob->obmat);
- }
- else {
- DRW_shgroup_call_add(shgrp, geom, ob->obmat);
- }
+ if (is_sculpt_mode) {
+ DRW_shgroup_call_sculpt_add(shgrp, ob, ob->obmat);
+ }
+ else {
+ DRW_shgroup_call_add(shgrp, geom, ob->obmat);
}
}
if (is_wire && shgrp != NULL) {
@@ -392,12 +365,18 @@ static void overlay_draw_scene(void *vedata)
OVERLAY_Data *data = vedata;
OVERLAY_PassList *psl = data->psl;
DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
+ DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
if (DRW_state_is_fbo()) {
GPU_framebuffer_bind(dfbl->default_fb);
}
DRW_draw_pass(psl->face_orientation_pass);
+
+ MULTISAMPLE_SYNC_ENABLE(dfbl, dtxl);
+
DRW_draw_pass(psl->face_wireframe_pass);
+
+ MULTISAMPLE_SYNC_DISABLE(dfbl, dtxl);
}
static void overlay_engine_free(void)
diff --git a/source/blender/draw/modes/shaders/overlay_face_wireframe_frag.glsl b/source/blender/draw/modes/shaders/overlay_face_wireframe_frag.glsl
index cefd4eab2e3..1a984b2fbc6 100644
--- a/source/blender/draw/modes/shaders/overlay_face_wireframe_frag.glsl
+++ b/source/blender/draw/modes/shaders/overlay_face_wireframe_frag.glsl
@@ -1,41 +1,23 @@
+
uniform vec3 wireColor;
uniform vec3 rimColor;
+flat in float edgeSharpness;
in float facing;
-in vec3 barycentric;
-flat in vec3 edgeSharpness;
out vec4 fragColor;
-float max_v3(vec3 v) { return max(v.x, max(v.y, v.z)); }
-
-/* In pixels */
-uniform float wireSize = 0.0; /* Expands the core of the wire (part that is 100% wire color) */
-const float wire_smooth = 1.2; /* Smoothing distance after the 100% core. */
-
-/* Alpha constants could be exposed in the future. */
-const float front_alpha = 0.35;
-const float rim_alpha = 0.75;
-
void main()
{
- vec3 dx = dFdx(barycentric);
- vec3 dy = dFdy(barycentric);
- vec3 d = vec3(
- length(vec2(dx.x, dy.x)),
- length(vec2(dx.y, dy.y)),
- length(vec2(dx.z, dy.z))
- );
- vec3 dist_to_edge = barycentric / d;
-
- vec3 fac = abs(dist_to_edge);
-
- fac = smoothstep(wireSize + wire_smooth, wireSize, fac);
+ if (edgeSharpness < 0.0) {
+ discard;
+ }
- float facing_clamped = clamp((gl_FrontFacing) ? facing : -facing, 0.0, 1.0);
+ float facing_clamped = clamp(abs(facing), 0.0, 1.0);
- vec3 final_front_col = mix(rimColor, wireColor, 0.05);
- fragColor = mix(vec4(rimColor, rim_alpha), vec4(final_front_col, front_alpha), facing_clamped);
+ vec3 final_front_col = mix(rimColor, wireColor, 0.4);
+ vec3 final_rim_col = mix(rimColor, wireColor, 0.1);
- fragColor.a *= max_v3(fac * edgeSharpness);
+ fragColor.rgb = mix(final_rim_col, final_front_col, facing_clamped);
+ fragColor.a = 1.0f;
}
diff --git a/source/blender/draw/modes/shaders/overlay_face_wireframe_vert.glsl b/source/blender/draw/modes/shaders/overlay_face_wireframe_vert.glsl
index 1ae204de60d..4e7560141f6 100644
--- a/source/blender/draw/modes/shaders/overlay_face_wireframe_vert.glsl
+++ b/source/blender/draw/modes/shaders/overlay_face_wireframe_vert.glsl
@@ -3,22 +3,11 @@ uniform mat4 ModelViewProjectionMatrix;
uniform mat4 ModelMatrix;
uniform mat3 NormalMatrix;
-uniform vec2 wireStepParam;
-
-vec3 get_edge_sharpness(vec3 wd)
-{
- bvec3 do_edge = greaterThan(wd, vec3(0.0));
- bvec3 force_edge = equal(wd, vec3(1.0));
- wd = clamp(wireStepParam.x * wd + wireStepParam.y, 0.0, 1.0);
- return clamp(wd * vec3(do_edge) + vec3(force_edge), 0.0, 1.0);
-}
+uniform float wireStepParam;
float get_edge_sharpness(float wd)
{
- bool do_edge = (wd > 0.0);
- bool force_edge = (wd == 1.0);
- wd = (wireStepParam.x * wd + wireStepParam.y);
- return clamp(wd * float(do_edge) + float(force_edge), 0.0, 1.0);
+ return (wd == 1.0) ? 1.0 : ((wd == 0.0) ? -1.0 : (wd + wireStepParam));
}
/* Geometry shader version */
@@ -51,35 +40,19 @@ void main()
#else /* SELECT_EDGES */
-/* Consecutive pos of the nth vertex
- * Only valid for first vertex in the triangle.
- * Assuming GL_FRIST_VERTEX_CONVENTION. */
-in vec3 pos0;
-in vec3 pos1;
-in vec3 pos2;
-in float wd0; /* wiredata */
-in float wd1;
-in float wd2;
+in vec3 pos;
in vec3 nor;
+in float wd;
out float facing;
-out vec3 barycentric;
-flat out vec3 edgeSharpness;
+flat out float edgeSharpness;
void main()
{
- int v_n = gl_VertexID % 3;
-
- barycentric = vec3(equal(ivec3(2, 0, 1), ivec3(v_n)));
-
- vec3 wb = vec3(wd0, wd1, wd2);
- edgeSharpness = get_edge_sharpness(wb);
-
- /* Don't generate any fragment if there is no edge to draw. */
- vec3 pos = (!any(greaterThan(edgeSharpness, vec3(0.04))) && (v_n == 0)) ? pos1 : pos0;
-
gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0);
+ edgeSharpness = get_edge_sharpness(wd);
+
facing = normalize(NormalMatrix * nor).z;
#ifdef USE_WORLD_CLIP_PLANES