[Bf-blender-cvs] [d0f7ab27a89] blender2.8: Wireframe: Optimization for intel GPUs.

Clément Foucault noreply at git.blender.org
Sun Jun 3 15:17:38 CEST 2018


Commit: d0f7ab27a898757fe444ac778bf072c268042feb
Author: Clément Foucault
Date:   Sun Jun 3 15:13:33 2018 +0200
Branches: blender2.8
https://developer.blender.org/rBd0f7ab27a898757fe444ac778bf072c268042feb

Wireframe: Optimization for intel GPUs.

Intel GPU take more advantage of the geometry shader than other vendors.

Using a simple geom shader approach in this case is more performant.

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

M	source/blender/draw/CMakeLists.txt
M	source/blender/draw/modes/overlay_mode.c
A	source/blender/draw/modes/shaders/overlay_face_wireframe_geom.glsl
M	source/blender/draw/modes/shaders/overlay_face_wireframe_vert.glsl

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

diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt
index 2b6d261d43e..40fd8762821 100644
--- a/source/blender/draw/CMakeLists.txt
+++ b/source/blender/draw/CMakeLists.txt
@@ -279,6 +279,7 @@ data_to_c_simple(modes/shaders/edit_normals_geom.glsl SRC)
 data_to_c_simple(modes/shaders/overlay_face_orientation_frag.glsl SRC)
 data_to_c_simple(modes/shaders/overlay_face_orientation_vert.glsl SRC)
 data_to_c_simple(modes/shaders/overlay_face_wireframe_vert.glsl SRC)
+data_to_c_simple(modes/shaders/overlay_face_wireframe_geom.glsl SRC)
 data_to_c_simple(modes/shaders/overlay_face_wireframe_frag.glsl SRC)
 data_to_c_simple(modes/shaders/object_empty_image_frag.glsl SRC)
 data_to_c_simple(modes/shaders/object_empty_image_vert.glsl SRC)
diff --git a/source/blender/draw/modes/overlay_mode.c b/source/blender/draw/modes/overlay_mode.c
index 505472460a1..131a9bc10db 100644
--- a/source/blender/draw/modes/overlay_mode.c
+++ b/source/blender/draw/modes/overlay_mode.c
@@ -28,6 +28,7 @@
 #include "BKE_object.h"
 
 #include "GPU_shader.h"
+#include "GPU_extensions.h"
 #include "DRW_render.h"
 
 #include "draw_mode_engines.h"
@@ -68,6 +69,7 @@ extern char datatoc_overlay_face_orientation_frag_glsl[];
 extern char datatoc_overlay_face_orientation_vert_glsl[];
 
 extern char datatoc_overlay_face_wireframe_vert_glsl[];
+extern char datatoc_overlay_face_wireframe_geom_glsl[];
 extern char datatoc_overlay_face_wireframe_frag_glsl[];
 
 extern struct GlobalsUboStorage ts; /* draw_common.c */
@@ -91,8 +93,13 @@ static void overlay_engine_init(void *vedata)
 	}
 
 	if (!e_data.face_wireframe_sh) {
+		char *wireframe_geom = NULL;
+		if (GPU_type_matches(GPU_DEVICE_INTEL, GPU_OS_ANY, GPU_DRIVER_ANY)) {
+			wireframe_geom = datatoc_overlay_face_wireframe_geom_glsl;
+		}
 		e_data.face_wireframe_sh = DRW_shader_create(
-		        datatoc_overlay_face_wireframe_vert_glsl, NULL,
+		        datatoc_overlay_face_wireframe_vert_glsl,
+		        wireframe_geom,
 		        datatoc_overlay_face_wireframe_frag_glsl, NULL);
 	}
 }
diff --git a/source/blender/draw/modes/shaders/overlay_face_wireframe_geom.glsl b/source/blender/draw/modes/shaders/overlay_face_wireframe_geom.glsl
new file mode 100644
index 00000000000..1cea418419e
--- /dev/null
+++ b/source/blender/draw/modes/shaders/overlay_face_wireframe_geom.glsl
@@ -0,0 +1,42 @@
+
+layout(triangles) in;
+layout(triangle_strip, max_vertices = 3) out;
+
+in vec2 ssPos[];
+in float facingOut[];
+
+flat out vec3 ssVec0;
+flat out vec3 ssVec1;
+flat out vec3 ssVec2;
+out float facing;
+
+#define NO_EDGE vec3(10000.0);
+
+vec3 compute_vec(vec2 v0, vec2 v1)
+{
+	vec2 v = normalize(v1 - v0);
+	v = vec2(-v.y, v.x);
+	return vec3(v, -dot(v, v0));
+}
+
+void main(void)
+{
+	vec3 facings = vec3(facingOut[0], facingOut[1], facingOut[2]);
+	bvec3 do_edge = greaterThan(abs(facings), vec3(1.0));
+	facings = fract(facings) - clamp(-sign(facings), 0.0, 1.0);
+
+	ssVec0 = do_edge.x ? compute_vec(ssPos[0], ssPos[1]) : NO_EDGE;
+	ssVec1 = do_edge.y ? compute_vec(ssPos[1], ssPos[2]) : NO_EDGE;
+	ssVec2 = do_edge.z ? compute_vec(ssPos[2], ssPos[0]) : NO_EDGE;
+
+	gl_Position = gl_in[0].gl_Position;
+	facing = facings.x;
+	EmitVertex();
+	gl_Position = gl_in[1].gl_Position;
+	facing = facings.y;
+	EmitVertex();
+	gl_Position = gl_in[2].gl_Position;
+	facing = facings.z;
+	EmitVertex();
+	EndPrimitive();
+}
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 67f4a5c7668..2cd888e7537 100644
--- a/source/blender/draw/modes/shaders/overlay_face_wireframe_vert.glsl
+++ b/source/blender/draw/modes/shaders/overlay_face_wireframe_vert.glsl
@@ -1,3 +1,8 @@
+
+#ifdef GPU_INTEL
+#define USE_GEOM_SHADER
+#endif
+
 uniform mat4 ModelViewProjectionMatrix;
 uniform mat4 ModelViewMatrix;
 uniform mat4 ProjectionMatrix;
@@ -9,10 +14,15 @@ uniform float nearDist;
 uniform samplerBuffer vertData;
 uniform isamplerBuffer faceIds;
 
+#ifdef USE_GEOM_SHADER
+out vec2 ssPos;
+out float facingOut; /* abs(facing) > 1.0 if we do edge */
+#else
 flat out vec3 ssVec0;
 flat out vec3 ssVec1;
 flat out vec3 ssVec2;
 out float facing;
+#endif
 
 /* project to screen space */
 vec2 proj(vec4 pos)
@@ -67,6 +77,21 @@ vec3 get_vertex_pos(int v_id)
 
 void main()
 {
+#ifdef USE_GEOM_SHADER
+	int v_id = texelFetch(faceIds, gl_VertexID).r;
+
+	bool do_edge = v_id < 0;
+	v_id = abs(v_id) - 1;
+
+	vec3 pos = get_vertex_pos(v_id);
+	vec3 nor = get_vertex_nor(v_id);
+	facingOut = normalize(NormalMatrix * nor).z;
+	facingOut += (do_edge) ? ((facingOut > 0.0) ? 2.0 : -2.0) : 0.0;
+
+	gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0);
+	ssPos = proj(gl_Position);
+
+#else
 
 	int v_0 = (gl_VertexID / 3) * 3;
 	int v_n = gl_VertexID % 3;
@@ -102,5 +127,6 @@ void main()
 	gl_Position = p_pos[v_n];
 
 	vec3 nor = get_vertex_nor(v_id[v_n]);
-	facing = (NormalMatrix * nor).z;
+	facing = normalize(NormalMatrix * nor).z;
+#endif
 }



More information about the Bf-blender-cvs mailing list