-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtesseval.glsl
151 lines (125 loc) · 3.71 KB
/
tesseval.glsl
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
#version 410
layout(triangles, equal_spacing, cw) in;
in vec3 tcPosition[];
in vec3 tcNormal[];
out vec4 Vertex;
out vec3 Normal;
out vec3 light;
uniform mat4 MVMatrix;
uniform mat4 MVPMatrix;
uniform vec3 LightPosition;
uniform vec3 LightColor;
uniform float TangentLength;
struct point {
vec3 p, n;
};
float rand(vec2 co)
{
return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);
}
point bezier(vec3 p0, vec3 p3, vec3 n1, vec3 n2, float t) {
vec3 t1, t2, e1, e2, tangent;
vec3 v, n;
e1 = p3 - p0;
e2 = p0 - p3;
t1 = cross(cross(n1, e1), n1); // Create the vector pointing toward the curve.
t2 = cross(cross(n2, e2), n2);
float l = length(e1);
t1 = normalize(t1) * (l * TangentLength);
t2 = normalize(t2) * (l * TangentLength);
float nt = 1 - t;
vec3 p1 = p0 + t1;
vec3 p2 = p3 + t2;
v = nt * nt * nt * p0 +
3 * nt * nt * t * p1 +
3 * nt * t * t * p2 +
t * t * t * p3;
tangent = 3 * nt * nt * (p1 - p0) +
6 * nt * t * (p2 - p1) +
3 * t * t * (p3 - p2);
n = cross(tangent, nt * cross(n1, e1) + t * cross(e2, n2));
//n = n1 + n2;
n = normalize(n);
point p;
p.p = v;
p.n = n;
return p;
}
/** We did not use Bézier triangles
point bezierTriangle(vec3 a, vec3 b, vec3 c, vec3 na, vec3 nb, vec3 nc, float s, float t, float u) {
vec3 eab, ebc, eca;
vec3 ab, ba, bc, cb, ca, ac, abc;
eab = b - a;
ebc = c - b;
eca = a - c;
ab = cross(cross(na, eab), na);
ba = cross(cross(nb, -eab), nb);
bc = cross(cross(nb, ebc), nb);
cb = cross(cross(nc, -ebc), nc);
ca = cross(cross(nc, eca), nc);
ac = cross(cross(na, -eca), na);
float lab = length(eab) * TangentLength;
float lbc = length(ebc) * TangentLength;
float lca = length(eca) * TangentLength;
ab = a + normalize(ab) * lab;
ba = b + normalize(ba) * lab;
bc = b + normalize(bc) * lbc;
cb = c + normalize(cb) * lbc;
ca = c + normalize(ca) * lca;
ac = a + normalize(ac) * lca;
abc = (ab + ba + bc + cb + ca + ac) / 6;
vec3 v = b * t * t * t +
3 * ba * s * t * t +
3 * bc * t * t * u + //
3 * ab * s * s * t +
6 * abc * s * t * u +
3 * cb * t * u * u + //
a * s * s * s +
3 * ac * s * s * u +
3 * ca * s * u * u +
c * u * u * u;
point p;
p.p = v;
p.n = na * s + nb * t + nc * u;
return p;
}
*/
void main()
{
/** the new vertex (p) can be found like this.
vec3 p0 = gl_TessCoord.x * tcPosition[0];
vec3 p1 = gl_TessCoord.y * tcPosition[1];
vec3 p2 = gl_TessCoord.z * tcPosition[2];
vec3 p = p0 + p1 + p2;
/**/
point middle;
/* using basic bezier */
float t1 = 0.5;
// if gl_TessCoord.z is 1.0, finding t1 will cause division by zero
if (gl_TessCoord.z < 1.0)
t1 = gl_TessCoord.y / (gl_TessCoord.x + gl_TessCoord.y);
// finding the point and normal of the v0 - v1 edge
point edge = bezier(tcPosition[0], tcPosition[1], tcNormal[0], tcNormal[1], t1);
float t2 = gl_TessCoord.z;
// finding the final point and normal on the curve between first edge and v2
middle = bezier(edge.p, tcPosition[2], edge.n, tcNormal[2], t2);
/* using bezier triangle *
middle = bezierTriangle(tcPosition[0], tcPosition[1], tcPosition[2],
tcNormal[0], tcNormal[1], tcNormal[2],
gl_TessCoord.x, gl_TessCoord.y, gl_TessCoord.z);
/**/
/** this was used when we did vertex lighting
light = vec3(middle.n);
/**/
// multiplying the Vertex with projection matrix, to position it on screen
//vec4 Vertex = vec4((p0 + p1 + p2), 1);
Vertex = vec4(middle.p, 1);
gl_Position = MVPMatrix * Vertex;
Normal = (MVMatrix*vec4(middle.n, 0.0)).xyz;
/**
vec3 to_light = LightPosition - (MVMatrix*Vertex).xyz;
vec3 n_to_light = normalize(to_light);
float intense = clamp(dot(normal, n_to_light.xyz), 0.0, 1.0);
light = intense * 0.95 * LightColor + 0.05;
/**/
}