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

edit_mesh_overlay_geom_tri.glsl « shaders « modes « draw « blender « source - git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: e0ec6e50dc2f4f2bbbdcba4b1f2ee4537bd3b090 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208

/* Solid Wirefram implementation
 * Mike Erwin, Clément Foucault */

/* This shader follows the principles of
 * http://developer.download.nvidia.com/SDK/10/direct3d/Source/SolidWireframe/Doc/SolidWireframe.pdf */

layout(triangles) in;

/* This is not perfect. Only a subset of intel gpus are affected.
 * This fix have some performance impact.
 * TODO Refine the range to only affect GPUs. */

#ifdef EDGE_FIX
/* To fix the edge artifacts, we render
 * an outline strip around the screenspace
 * triangle. Order is important.
 * TODO diagram
 */

#ifdef VERTEX_SELECTION
layout(triangle_strip, max_vertices=23) out;
#else
layout(triangle_strip, max_vertices=17) out;
#endif
#else
layout(triangle_strip, max_vertices=3) out;
#endif

uniform mat4 ProjectionMatrix;
uniform vec2 viewportSize;

in vec4 vPos[];
in vec4 pPos[];
in ivec4 vData[];
#ifdef VERTEX_FACING
in float vFacing[];
#endif

/* these are the same for all vertices
 * and does not need interpolation */
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
#ifdef VERTEX_FACING
out float facing;
#endif

/* See fragment shader */
flat out vec2 ssPos[3];

#define FACE_ACTIVE     (1 << 2)
#define FACE_SELECTED   (1 << 3)

/* project to screen space */
vec2 proj(vec4 pos)
{
	return (0.5 * (pos.xy / pos.w) + 0.5) * viewportSize;
}

void doVertex(int v)
{
#ifdef VERTEX_SELECTION
	vertexColor = EDIT_MESH_vertex_color(vData[v].x).rgb;
#endif

#ifdef VERTEX_FACING
	facing = vFacing[v];
#endif

	gl_Position = pPos[v];

	EmitVertex();
}

void doLoopStrip(int v, vec3 offset)
{
	doVertex(v);

	gl_Position.xyz += offset;

	EmitVertex();
}

#ifdef ANTI_ALIASING
#define Z_OFFSET 0.008
#else
#define Z_OFFSET 0.0
#endif

void main()
{
	/* Edge */
	ivec3 eflag; vec3 ecrease, ebweight;
	for (int v = 0; v < 3; ++v) {
		flag[v] = eflag[v] = vData[v].y | (vData[v].x << 8);
		edgesCrease[v] = ecrease[v] = vData[v].z / 255.0;
		edgesBweight[v] = ebweight[v] = vData[v].w / 255.0;
	}

	/* Face */
	if ((vData[0].x & FACE_ACTIVE) != 0)
		faceColor = colorFaceSelect;
	else if ((vData[0].x & FACE_SELECTED) != 0)
		faceColor = colorFaceSelect;
	else
		faceColor = colorFace;

	/* Vertex */
	vec2 pos[3];
	ssPos[0] = pos[0] = proj(pPos[0]);
	ssPos[1] = pos[1] = proj(pPos[1]);
	ssPos[2] = pos[2] = proj(pPos[2]);

	doVertex(0);
	doVertex(1);
	doVertex(2);

#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;
		}

		/* 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;
		}
	}

	/* to not let face color bleed */
	faceColor.a = 0.0;

	/* Start with the same last vertex to create a
	 * degenerate triangle in order to "create"
	 * a new triangle strip */
	for (int i = 2; i < 5; ++i) {
		int vbe = (i - 1) % 3;
		int vaf = (i + 1) % 3;
		int v = i % 3;

		doLoopStrip(v, vec3(fixvec[v], Z_OFFSET));

		/* Only shade the edge that we are currently drawing.
		 * (fix corner bleeding) */
		flag[vbe] |= (EDGE_EXISTS & eflag[vbe]);
		flag[vaf] &= ~EDGE_EXISTS;
		flag[v]   &= ~EDGE_EXISTS;
		doLoopStrip(vaf, vec3(fixvecaf[v], Z_OFFSET));

		/* corner vertices should not draw edges but draw point only */
		flag[vbe] &= ~EDGE_EXISTS;
#ifdef VERTEX_SELECTION
		doLoopStrip(vaf, vec3(cornervec[vaf], Z_OFFSET));
#endif
	}

	/* finish the loop strip */
	doLoopStrip(2, vec3(fixvec[2], Z_OFFSET));
#endif

	EndPrimitive();
}