[Bf-blender-cvs] [ce80e00a7c6] blender2.8: Edit Mesh: Simplify the overlay shader.

Clément Foucault noreply at git.blender.org
Sat Jun 16 15:49:13 CEST 2018


Commit: ce80e00a7c68fb1c77232f94f620fcf6e7c13107
Author: Clément Foucault
Date:   Sat Jun 16 15:15:37 2018 +0200
Branches: blender2.8
https://developer.blender.org/rBce80e00a7c68fb1c77232f94f620fcf6e7c13107

Edit Mesh: Simplify the overlay shader.

Remove all the clip cases and just pass the vertices screen position to the
fragment shader.

This does put a bit more pressure on the fragment shader but it seems to be
faster than before. And it simplify the code a lot.

It seems to fix some long standing issue on some intel GPU.

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

M	source/blender/draw/modes/shaders/edit_mesh_overlay_frag.glsl
M	source/blender/draw/modes/shaders/edit_mesh_overlay_geom_edge.glsl
M	source/blender/draw/modes/shaders/edit_mesh_overlay_geom_tri.glsl
M	source/blender/draw/modes/shaders/edit_mesh_overlay_loosevert_vert.glsl

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

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 4627643cf86..9fa6220da4d 100644
--- a/source/blender/draw/modes/shaders/edit_mesh_overlay_frag.glsl
+++ b/source/blender/draw/modes/shaders/edit_mesh_overlay_frag.glsl
@@ -10,11 +10,11 @@
  * TODO Refine the range to only affect GPUs. */
 
 uniform float faceAlphaMod;
+
 flat in vec3 edgesCrease;
 flat in vec3 edgesBweight;
 flat in vec4 faceColor;
 flat in ivec3 flag;
-flat in int clipCase;
 #ifdef VERTEX_SELECTION
 in vec3 vertexColor;
 #endif
@@ -22,25 +22,7 @@ in vec3 vertexColor;
 in float facing;
 #endif
 
-/* We use a vec4[2] interface to pass edge data
- * (without fragmenting memory accesses)
- *
- * There are 2 cases :
- *
- * - Simple case : geometry shader return edge distances
- *   in the first 2 components of the first vec4.
- *   This needs noperspective interpolation.
- *   The rest is filled with vertex screen positions.
- *   eData2[0] actually contain v2
- *   eData2[1] actually contain v1
- *   eData2[2] actually contain v0
- *
- * - Hard case : two 2d edge corner are described by each
- *   vec4 as origin and direction. This is constant over
- *   the triangle and use to detect the correct case. */
-
-noperspective in vec2 eData1;
-flat in vec2 eData2[3];
+flat in vec2 ssPos[3];
 
 out vec4 FragColor;
 
@@ -49,38 +31,21 @@ out vec4 FragColor;
 
 #define LARGE_EDGE_SIZE 2.0
 
-
 /* Style Parameters in pixel */
 
-/* Array to retrieve vert/edge indices */
-const ivec3 clipEdgeIdx[6] = ivec3[6](
-	ivec3(1, 0, 2),
-	ivec3(2, 0, 1),
-	ivec3(2, 1, 0),
-	ivec3(2, 1, 0),
-	ivec3(2, 0, 1),
-	ivec3(1, 0, 2)
-);
-
-const ivec3 clipPointIdx[6] = ivec3[6](
-	ivec3(0, 1, 2),
-	ivec3(0, 2, 1),
-	ivec3(0, 2, 1),
-	ivec3(1, 2, 0),
-	ivec3(1, 2, 0),
-	ivec3(2, 1, 0)
-);
-
-void colorDist(vec4 color, float dist)
+void distToEdgeAndPoint(vec2 dir, vec2 ori, out float edge, out float point)
 {
-	FragColor = (dist < 0) ? color : FragColor;
+	dir = normalize(dir.xy);
+	vec2 of = gl_FragCoord.xy - ori;
+	point = dot(of, of);
+	float dof = dot(dir, of);
+	edge = sqrt(abs(point - dof * dof));
+	point = sqrt(point);
 }
 
-float distToEdge(vec2 o, vec2 dir)
+void colorDist(vec4 color, float dist)
 {
-	vec2 af = gl_FragCoord.xy - o;
-	float daf = dot(dir, af);
-	return sqrt(abs(dot(af, af) - daf * daf));
+	FragColor = (dist < 0) ? color : FragColor;
 }
 
 #ifdef ANTI_ALIASING
@@ -99,42 +64,13 @@ void main()
 	vec3 e, p;
 
 	/* Step 1 : Computing Distances */
-
-	if (clipCase == 0) {
-		e.xy = eData1;
-
-		/* computing missing distance */
-		vec2 dir = normalize(eData2[2] - eData2[1]);
-		e.z = distToEdge(eData2[2], dir);
-
-		p.x = distance(eData2[2], gl_FragCoord.xy);
-		p.y = distance(eData2[1], gl_FragCoord.xy);
-		p.z = distance(eData2[0], gl_FragCoord.xy);
-	}
-	else {
-		ivec3 eidxs = clipEdgeIdx[clipCase - 1];
-		ivec3 pidxs = clipPointIdx[clipCase - 1];
-
-		e[eidxs.x] = distToEdge(eData1, eData2[0]);
-		e[eidxs.y] = distToEdge(eData2[1], eData2[2]);
-
-		/* Three edges visible cases */
-		if (clipCase == 1 || clipCase == 2 || clipCase == 4) {
-			e[eidxs.z] = distToEdge(eData1, normalize(eData2[1] - eData1));
-			p[pidxs.y] = distance(eData2[1], gl_FragCoord.xy);
-		}
-		else {
-			e[eidxs.z] = 1e10; /* off screen */
-			p[pidxs.y] = 1e10; /* off screen */
-		}
-
-		p[pidxs.x] = distance(eData1, gl_FragCoord.xy);
-		p[pidxs.z] = 1e10; /* off screen */
-	}
+	distToEdgeAndPoint((ssPos[1] - ssPos[0]) + 1e-8, ssPos[0], e.z, p.x);
+	distToEdgeAndPoint((ssPos[2] - ssPos[1]) + 1e-8, ssPos[1], e.x, p.y);
+	distToEdgeAndPoint((ssPos[0] - ssPos[2]) + 1e-8, ssPos[2], e.y, p.z);
 
 	/* Step 2 : coloring (order dependant) */
 
-	/* First */
+	/* Face */
 	FragColor = faceColor;
 	FragColor.a *= faceAlphaMod;
 
diff --git a/source/blender/draw/modes/shaders/edit_mesh_overlay_geom_edge.glsl b/source/blender/draw/modes/shaders/edit_mesh_overlay_geom_edge.glsl
index 0089f3b004c..88cb6c07a94 100644
--- a/source/blender/draw/modes/shaders/edit_mesh_overlay_geom_edge.glsl
+++ b/source/blender/draw/modes/shaders/edit_mesh_overlay_geom_edge.glsl
@@ -24,7 +24,6 @@ flat out vec3 edgesCrease;
 flat out vec3 edgesBweight;
 flat out vec4 faceColor;
 flat out ivec3 flag;
-flat out int clipCase;
 #ifdef VERTEX_SELECTION
 out vec3 vertexColor;
 #endif
@@ -33,41 +32,17 @@ out float facing;
 #endif
 
 /* See fragment shader */
-noperspective out vec2 eData1;
-flat out vec2 eData2[3];
+flat out vec2 ssPos[3];
 
 #define FACE_ACTIVE     (1 << 2)
 #define FACE_SELECTED   (1 << 3)
 
-/* Table 1. Triangle Projection Cases */
-const ivec4 clipPointsIdx[6] = ivec4[6](
-	ivec4(0, 1, 2, 2),
-	ivec4(0, 2, 1, 1),
-	ivec4(0, 0, 1, 2),
-	ivec4(1, 2, 0, 0),
-	ivec4(1, 1, 0, 2),
-	ivec4(2, 2, 0, 1)
-);
-
 /* project to screen space */
 vec2 proj(vec4 pos)
 {
 	return (0.5 * (pos.xy / pos.w) + 0.5) * viewportSize;
 }
 
-float dist(vec2 pos[3], vec2 vpos, int v)
-{
-	/* endpoints of opposite edge */
-	vec2 e1 = pos[(v + 1) % 3];
-	vec2 e2 = pos[(v + 2) % 3];
-	/* Edge normalized vector */
-	vec2 dir = normalize(e2 - e1);
-	/* perpendicular to dir */
-	vec2 orthogonal = vec2(-dir.y, dir.x);
-
-	return abs(dot(vpos - e1, orthogonal));
-}
-
 void doVertex(int v, vec4 pos)
 {
 #ifdef VERTEX_SELECTION
@@ -85,8 +60,6 @@ void doVertex(int v, vec4 pos)
 
 void main()
 {
-	clipCase = 0;
-
 	/* Face */
 	faceColor = vec4(0.0);
 
@@ -117,19 +90,16 @@ void main()
 	}
 
 	/* Edge / Vert data */
-	eData1 = vec2(1e10);
-	eData2[0] = vec2(1e10);
-	eData2[2] = pos[0];
-	eData2[1] = pos[1];
-	flag[0] = (vData[0].x << 8);
+	ssPos[0] = ssPos[2] = pos[0];
+	ssPos[1] = pos[1];
+	flag[0] = flag[2] = (vData[0].x << 8);
 	flag[1] = (vData[1].x << 8);
-	flag[2] = 0;
 
 	doVertex(0, pPos[0] + vec4(-dirs1.xy, 0.0, 0.0));
 	doVertex(0, pPos[0] + vec4( dirs1.zw, 0.0, 0.0));
 	doVertex(0, pPos[0] + vec4(-dirs1.zw, 0.0, 0.0));
 
-	flag[2] = vData[0].y | (vData[0].x << 8);
+	flag[2] |= vData[0].y;
 	edgesCrease[2] = vData[0].z / 255.0;
 	edgesBweight[2] = vData[0].w / 255.0;
 
diff --git a/source/blender/draw/modes/shaders/edit_mesh_overlay_geom_tri.glsl b/source/blender/draw/modes/shaders/edit_mesh_overlay_geom_tri.glsl
index 890144982ab..e0ec6e50dc2 100644
--- a/source/blender/draw/modes/shaders/edit_mesh_overlay_geom_tri.glsl
+++ b/source/blender/draw/modes/shaders/edit_mesh_overlay_geom_tri.glsl
@@ -52,49 +52,17 @@ out float facing;
 #endif
 
 /* See fragment shader */
-noperspective out vec2 eData1;
-flat out vec2 eData2[3];
+flat out vec2 ssPos[3];
 
 #define FACE_ACTIVE     (1 << 2)
 #define FACE_SELECTED   (1 << 3)
 
-/* Table 1. Triangle Projection Cases */
-const ivec4 clipPointsIdx[6] = ivec4[6](
-	ivec4(0, 1, 2, 2),
-	ivec4(0, 2, 1, 1),
-	ivec4(0, 0, 1, 2),
-	ivec4(1, 2, 0, 0),
-	ivec4(1, 1, 0, 2),
-	ivec4(2, 2, 0, 1)
-);
-
 /* project to screen space */
 vec2 proj(vec4 pos)
 {
 	return (0.5 * (pos.xy / pos.w) + 0.5) * viewportSize;
 }
 
-float dist(vec2 pos[3], vec2 vpos, int v)
-{
-	/* endpoints of opposite edge */
-	vec2 e1 = pos[(v + 1) % 3];
-	vec2 e2 = pos[(v + 2) % 3];
-	/* Edge normalized vector */
-	vec2 dir = normalize(e2 - e1);
-	/* perpendicular to dir */
-	vec2 orthogonal = vec2(-dir.y, dir.x);
-
-	return abs(dot(vpos - e1, orthogonal));
-}
-
-vec4 getClipData(vec2 pos[3], ivec2 vidx)
-{
-	vec2 A = pos[vidx.x];
-	vec2 Adir = normalize(A - pos[vidx.y]);
-
-	return vec4(A, Adir);
-}
-
 void doVertex(int v)
 {
 #ifdef VERTEX_SELECTION
@@ -127,21 +95,6 @@ void doLoopStrip(int v, vec3 offset)
 
 void main()
 {
-	/* First we detect which case we are in */
-	clipCase = 0;
-
-	/* if perspective */
-	if (ProjectionMatrix[3][3] == 0.0) {
-		/* See Table 1. Triangle Projection Cases  */
-		clipCase += int(pPos[0].z / pPos[0].w < -1 || vPos[0].z > 0.0) * 4;
-		clipCase += int(pPos[1].z / pPos[1].w < -1 || vPos[1].z > 0.0) * 2;
-		clipCase += int(pPos[2].z / pPos[2].w < -1 || vPos[2].z > 0.0) * 1;
-	}
-
-	/* If triangle is behind nearplane, early out */
-	if (clipCase == 7)
-		return;
-
 	/* Edge */
 	ivec3 eflag; vec3 ecrease, ebweight;
 	for (int v = 0; v < 3; ++v) {
@@ -159,138 +112,97 @@ void main()
 		faceColor = colorFace;
 
 	/* Vertex */
-	vec2 pos[3] = vec2[3](proj(pPos[0]), proj(pPos[1]), proj(pPos[2]));
+	vec2 pos[3];
+	ssPos[0] = pos[0] = proj(pPos[0]);
+	ssPos[1] = pos[1] = proj(pPos[1]);
+	ssPos[2] = pos[2] = proj(pPos[2]);
 
-	/* Simple case : compute edge distances in geometry shader */
-	if (clipCase == 0) {
+	doVertex(0);
+	doVertex(1);
+	doVertex(2);
 
-		/* Packing screen positions and 2 distances */
-		eData2[0] = pos[2];
-		eData2[1] = pos[1];
-		eData2[2] = pos[0];
+#ifdef EDGE_FIX
+	vec2 fixvec[6];
+	vec2 fixvecaf[6];
+	vec2 cornervec[3];
+
+	/* This fix the case when 2 vertices are perfectly aligned
+	 * and corner vectors have nowhere to go.
+	 * ie: length(cornervec[i]) == 0 */
+	const float epsilon = 1e-2; /* in pixel so not that much */
+	const vec2 bias[3] = vec2[3](
+		vec2( epsilon,  epsilon),
+		vec2(-epsilon,  epsilon),
+		vec2(     0.0, -epsilon)
+	);
+
+	for (int i = 0; i < 3; ++i) {
+		int i1 = (i + 1) % 3;
+		int i2 = (i + 2) % 3;
+
+		vec2 v1 = ssPos[i] + bias[i];
+		vec2 v2 = ssPos[i1] + bias[i1];
+		vec2 v3 = ssPos[i2] + bias[i2];
+
+		/* Edge normalized vector */
+		vec2 dir = normalize(v2 - v1);
+		vec2 dir2 = normalize(v3 - v1);
+
+		cornervec[i] = -normalize(dir + dir2);
+
+		/* perpendicular to dir */
+		vec2 perp = vec2(-dir.y, dir.x);
+
+		/* Backface case */
+		if (dot(perp, dir2) > 0) {
+			perp = -perp;
+		}
 
-		/* Only pass the first 2 distances */
-		for (int v = 0; v < 2; ++v) {
-			eData1[v] = dist(pos, pos[v], v);
-			doVertex(v);
-			eData1[v] = 0.0;
+		/* Make it view independent */
+		perp *= sizeEdgeFix / viewportSize;
+		cornervec[i] *= sizeEdgeFix / viewportSize;
+		fixvec[i] = fixvecaf[i] = perp;
+
+		/* Perspective */
+		if (ProjectionMatrix[3][3] == 0.0) {
+			/* vPos[i].z is negative and we don't want
+			 * our fixvec to be flipped */
+			fixvec[i] *= -vPos[i].z;
+			fixvecaf[i] *= -vPos[i1].z;
+			cornervec[i] *= -vPos[i].z;
 		}
+	}
 
-		/* and the last vertex */
-		doVertex(2);
+	/* to not let face color bleed */
+	faceColor.a = 0.0;
 
-#ifdef EDGE_FIX
-		vec2 fixvec[6];
-		vec2 fixvecaf[6];
-		vec2

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list