[Bf-blender-cvs] [542462d35c5] blender2.8: Workbench: Xray: Add selected/active non-occluded outlines

Clément Foucault noreply at git.blender.org
Sun Jun 10 19:56:49 CEST 2018


Commit: 542462d35c5c17742aa4d3d17c13bbbf312fe7a3
Author: Clément Foucault
Date:   Sun Jun 10 19:35:25 2018 +0200
Branches: blender2.8
https://developer.blender.org/rB542462d35c5c17742aa4d3d17c13bbbf312fe7a3

Workbench: Xray: Add selected/active non-occluded outlines

This Fix the problem when multiple objects are selected and one of them
occlude the others. You cannot see clearly what is selected.

With this option, selection is more clear when Xray mode is enabled.

===================================================================

M	source/blender/draw/CMakeLists.txt
M	source/blender/draw/modes/object_mode.c
A	source/blender/draw/modes/shaders/object_outline_prepass_geom.glsl
A	source/blender/draw/modes/shaders/object_outline_prepass_vert.glsl

===================================================================

diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt
index f049fc87205..7d869982f29 100644
--- a/source/blender/draw/CMakeLists.txt
+++ b/source/blender/draw/CMakeLists.txt
@@ -286,6 +286,8 @@ data_to_c_simple(modes/shaders/object_empty_image_vert.glsl SRC)
 data_to_c_simple(modes/shaders/object_outline_resolve_frag.glsl SRC)
 data_to_c_simple(modes/shaders/object_outline_expand_frag.glsl SRC)
 data_to_c_simple(modes/shaders/object_outline_detect_frag.glsl SRC)
+data_to_c_simple(modes/shaders/object_outline_prepass_vert.glsl SRC)
+data_to_c_simple(modes/shaders/object_outline_prepass_geom.glsl SRC)
 data_to_c_simple(modes/shaders/object_outline_prepass_frag.glsl SRC)
 data_to_c_simple(modes/shaders/object_grid_frag.glsl SRC)
 data_to_c_simple(modes/shaders/object_grid_vert.glsl SRC)
diff --git a/source/blender/draw/modes/object_mode.c b/source/blender/draw/modes/object_mode.c
index c616a19bab0..0b90b9276b4 100644
--- a/source/blender/draw/modes/object_mode.c
+++ b/source/blender/draw/modes/object_mode.c
@@ -72,6 +72,8 @@ extern struct GPUUniformBuffer *globals_ubo; /* draw_common.c */
 extern struct GPUTexture *globals_ramp; /* draw_common.c */
 extern GlobalsUboStorage ts;
 
+extern char datatoc_object_outline_prepass_vert_glsl[];
+extern char datatoc_object_outline_prepass_geom_glsl[];
 extern char datatoc_object_outline_prepass_frag_glsl[];
 extern char datatoc_object_outline_resolve_frag_glsl[];
 extern char datatoc_object_outline_detect_frag_glsl[];
@@ -250,6 +252,7 @@ static struct {
 
 	/* fullscreen shaders */
 	GPUShader *outline_prepass_sh;
+	GPUShader *outline_prepass_wire_sh;
 	GPUShader *outline_resolve_sh;
 	GPUShader *outline_resolve_aa_sh;
 	GPUShader *outline_detect_sh;
@@ -341,6 +344,11 @@ static void OBJECT_engine_init(void *vedata)
 		/* Outline */
 		e_data.outline_prepass_sh = DRW_shader_create_3D(datatoc_object_outline_prepass_frag_glsl, NULL);
 
+		e_data.outline_prepass_wire_sh = DRW_shader_create(
+		            datatoc_object_outline_prepass_vert_glsl,
+		            datatoc_object_outline_prepass_geom_glsl,
+		            datatoc_object_outline_prepass_frag_glsl, NULL);
+
 		e_data.outline_resolve_sh = DRW_shader_create_fullscreen(datatoc_object_outline_resolve_frag_glsl, NULL);
 
 		e_data.outline_resolve_aa_sh = DRW_shader_create_with_lib(
@@ -580,6 +588,7 @@ static void OBJECT_engine_free(void)
 	MEM_SAFE_FREE(e_data.empty_image_format);
 	MEM_SAFE_FREE(e_data.empty_image_wire_format);
 	DRW_SHADER_FREE_SAFE(e_data.outline_prepass_sh);
+	DRW_SHADER_FREE_SAFE(e_data.outline_prepass_wire_sh);
 	DRW_SHADER_FREE_SAFE(e_data.outline_resolve_sh);
 	DRW_SHADER_FREE_SAFE(e_data.outline_resolve_aa_sh);
 	DRW_SHADER_FREE_SAFE(e_data.outline_detect_sh);
@@ -854,6 +863,7 @@ static void OBJECT_cache_init(void *vedata)
 	OBJECT_StorageList *stl = ((OBJECT_Data *)vedata)->stl;
 	DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
 	OBJECT_PrivateData *g_data;
+	const DRWContextState *draw_ctx = DRW_context_state_get();
 	/* TODO : use dpi setting for enabling the second pass */
 	const bool do_outline_expand = false;
 
@@ -870,13 +880,12 @@ static void OBJECT_cache_init(void *vedata)
 
 		GPUShader *sh = e_data.outline_prepass_sh;
 
-		/* Select */
-		g_data->outlines_select = shgroup_outline(psl->outlines, &g_data->id_ofs_select, sh);
+		if (draw_ctx->v3d->shading.flag & V3D_SHADING_XRAY) {
+			sh = e_data.outline_prepass_wire_sh;
+		}
 
-		/* Transform */
+		g_data->outlines_select = shgroup_outline(psl->outlines, &g_data->id_ofs_select, sh);
 		g_data->outlines_transform = shgroup_outline(psl->outlines, &g_data->id_ofs_transform, sh);
-
-		/* Active */
 		g_data->outlines_active = shgroup_outline(psl->outlines, &g_data->id_ofs_active, sh);
 
 		g_data->id_ofs_select = 0;
@@ -2087,7 +2096,13 @@ static void OBJECT_cache_populate(void *vedata, Object *ob)
 
 	if (do_outlines) {
 		if ((ob != draw_ctx->object_edit) && !((ob == draw_ctx->obact) && (draw_ctx->object_mode & OB_MODE_ALL_PAINT))) {
-			struct Gwn_Batch *geom = DRW_cache_object_surface_get(ob);
+			struct Gwn_Batch *geom;
+			if (v3d->shading.flag & V3D_SHADING_XRAY) {
+				geom = DRW_cache_object_edge_detection_get(ob, NULL);
+			}
+			else {
+				geom = DRW_cache_object_surface_get(ob);
+			}
 			if (geom) {
 				theme_id = DRW_object_wire_theme_get(ob, view_layer, NULL);
 				DRWShadingGroup *shgroup = shgroup_theme_id_to_outline_or(stl, theme_id, NULL);
diff --git a/source/blender/draw/modes/shaders/object_outline_prepass_geom.glsl b/source/blender/draw/modes/shaders/object_outline_prepass_geom.glsl
new file mode 100644
index 00000000000..c90195e11fd
--- /dev/null
+++ b/source/blender/draw/modes/shaders/object_outline_prepass_geom.glsl
@@ -0,0 +1,40 @@
+
+layout(lines_adjacency) in;
+layout(line_strip, max_vertices = 2) out;
+
+uniform mat4 ProjectionMatrix;
+
+in vec4 pPos[];
+in vec3 vPos[];
+
+void main()
+{
+	bool is_persp = (ProjectionMatrix[3][3] == 0.0);
+
+	vec3 view_vec = (is_persp) ? normalize(vPos[1]) : vec3(0.0, 0.0, -1.0);
+
+	vec3 v10 = vPos[0] - vPos[1];
+	vec3 v12 = vPos[2] - vPos[1];
+	vec3 v13 = vPos[3] - vPos[1];
+
+	vec3 n0 = cross(v12, v10);
+	vec3 n3 = cross(v13, v12);
+
+	float fac0 = dot(view_vec, n0);
+	float fac3 = dot(view_vec, n3);
+
+	/* If both adjacent verts are facing the camera the same way,
+	 * then it isn't an outline edge. */
+	if (sign(fac0) == sign(fac3))
+		return;
+
+	/* Don't outline if concave edge. */
+	/* That would hide a lot of non usefull edge but it flickers badly.
+	 * TODO revisit later... */
+	// if (dot(n0, v13) > 0.01)
+	// 	return;
+
+	gl_Position = pPos[1]; EmitVertex();
+	gl_Position = pPos[2]; EmitVertex();
+	EndPrimitive();
+}
diff --git a/source/blender/draw/modes/shaders/object_outline_prepass_vert.glsl b/source/blender/draw/modes/shaders/object_outline_prepass_vert.glsl
new file mode 100644
index 00000000000..ba824a7c007
--- /dev/null
+++ b/source/blender/draw/modes/shaders/object_outline_prepass_vert.glsl
@@ -0,0 +1,16 @@
+
+uniform mat4 ModelViewMatrix;
+uniform mat4 ModelViewProjectionMatrix;
+
+in vec3 pos;
+
+out vec4 pPos;
+out vec3 vPos;
+
+void main()
+{
+	vPos = (ModelViewMatrix * vec4(pos, 1.0)).xyz;
+	pPos = ModelViewProjectionMatrix * vec4(pos, 1.0);
+	/* Small bias to always be on top of the geom. */
+	pPos.z -= 1e-3;
+}



More information about the Bf-blender-cvs mailing list