1
|
//////////////////////////////////////////////////////////////////////////////////////////////
|
2
|
// Copyright 2016 Leszek Koltunski //
|
3
|
// //
|
4
|
// This file is part of Distorted. //
|
5
|
// //
|
6
|
// Distorted is free software: you can redistribute it and/or modify //
|
7
|
// it under the terms of the GNU General Public License as published by //
|
8
|
// the Free Software Foundation, either version 2 of the License, or //
|
9
|
// (at your option) any later version. //
|
10
|
// //
|
11
|
// Distorted is distributed in the hope that it will be useful, //
|
12
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
|
13
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
|
14
|
// GNU General Public License for more details. //
|
15
|
// //
|
16
|
// You should have received a copy of the GNU General Public License //
|
17
|
// along with Distorted. If not, see <http://www.gnu.org/licenses/>. //
|
18
|
//////////////////////////////////////////////////////////////////////////////////////////////
|
19
|
|
20
|
precision highp float;
|
21
|
precision highp int;
|
22
|
|
23
|
in vec3 a_Position; // Per-vertex position.
|
24
|
in vec3 a_Normal; // Per-vertex normal vector.
|
25
|
in vec3 a_Inflate; // This vector describes the direction this vertex needs to go when we 'inflate' the whole mesh.
|
26
|
// If the mesh is locally smooth, this is equal to the normal vector. Otherwise (on sharp edges) - no.
|
27
|
in vec2 a_TexCoordinate; // Per-vertex texture coordinate.
|
28
|
in float a_Tag; // Per-vertex tag. Connects the vertex (really the mesh component the vertex is a member of) to a vertex effect.
|
29
|
// An effect will only be active on a vertex iff (a_Tag & vTag[effect]) != 0. ( see VertexEffect.retSection() )
|
30
|
|
31
|
out vec3 v_Position; //
|
32
|
out vec3 v_endPosition; // for Transform Feedback only
|
33
|
|
34
|
#ifdef PREAPPLY
|
35
|
out vec3 v_Inflate; // Transform Feedback for preapply effects
|
36
|
#endif
|
37
|
|
38
|
out vec3 v_Normal; //
|
39
|
out vec2 v_TexCoordinate; //
|
40
|
|
41
|
uniform mat4 u_MVPMatrix; // the combined model/view/projection matrix.
|
42
|
uniform mat4 u_MVMatrix; // the combined model/view matrix.
|
43
|
uniform float u_Inflate; // how much should we inflate (>0.0) or deflate (<0.0) the mesh.
|
44
|
|
45
|
#if NUM_VERTEX>0
|
46
|
uniform int vNumEffects; // total number of vertex effects
|
47
|
uniform int vName[NUM_VERTEX]; // their names.
|
48
|
uniform vec4 vUniforms[3*NUM_VERTEX];// i-th effect is 3 consecutive vec4's: [3*i], [3*i+1], [3*i+2].
|
49
|
// The first vec4 is the Interpolated values,
|
50
|
// second vec4: first float - cache, next 3: Center, the third - the Region.
|
51
|
uniform int vTag[NUM_VERTEX]; // Tags of the vertex effects. Tags are used to connect an effect to a Mesh component.
|
52
|
|
53
|
//////////////////////////////////////////////////////////////////////////////////////////////
|
54
|
// HELPER FUNCTIONS
|
55
|
//////////////////////////////////////////////////////////////////////////////////////////////
|
56
|
// Return degree of the point as defined by the Region. Currently only supports spherical regions.
|
57
|
//
|
58
|
// Let 'PS' be the vector from point P (the current vertex) to point S (the center of the effect).
|
59
|
// Let region.xyz be the vector from point S to point O (the center point of the region sphere)
|
60
|
// Let region.w be the radius of the region sphere.
|
61
|
// (This all should work regardless if S is inside or outside of the sphere).
|
62
|
//
|
63
|
// Then, the degree of a point with respect to a given (spherical!) Region is defined by:
|
64
|
//
|
65
|
// If P is outside the sphere, return 0.
|
66
|
// Otherwise, let X be the point where the halfline SP meets the sphere - then return |PX|/|SX|,
|
67
|
// aka the 'degree' of point P.
|
68
|
//
|
69
|
// We solve the triangle OPX.
|
70
|
// We know the lengths |PO|, |OX| and the angle OPX, because cos(OPX) = cos(180-OPS) = -cos(OPS) = -PS*PO/(|PS|*|PO|)
|
71
|
// then from the law of cosines PX^2 + PO^2 - 2*PX*PO*cos(OPX) = OX^2 so PX = -a + sqrt(a^2 + OX^2 - PO^2)
|
72
|
// where a = PS*PO/|PS| but we are really looking for d = |PX|/(|PX|+|PS|) = 1/(1+ (|PS|/|PX|) ) and
|
73
|
// |PX|/|PS| = -b + sqrt(b^2 + (OX^2-PO^2)/PS^2) where b=PS*PO/|PS|^2 which can be computed with only one sqrt.
|
74
|
|
75
|
float degree(in vec4 region, in vec3 PS)
|
76
|
{
|
77
|
vec3 PO = PS + region.xyz;
|
78
|
float D = region.w*region.w-dot(PO,PO); // D = |OX|^2 - |PO|^2
|
79
|
|
80
|
if( D<=0.0 ) return 0.0;
|
81
|
|
82
|
float ps_sq = dot(PS,PS);
|
83
|
float one_over_ps_sq = 1.0/(ps_sq-(sign(ps_sq)-1.0)); // return 1.0 if ps_sq = 0.0
|
84
|
// Important: if we want to write
|
85
|
// b = 1/a if a!=0, b=1 otherwise
|
86
|
// we need to write that as
|
87
|
// b = 1 / ( a-(sign(a)-1) )
|
88
|
// [ and NOT 1 / ( a + 1 - sign(a) ) ]
|
89
|
// because the latter, if 0<a<2^-24,
|
90
|
// will suffer from round-off error and in this case
|
91
|
// a + 1.0 = 1.0 !! so 1 / (a+1-sign(a)) = 1/0 !
|
92
|
float DOT = dot(PS,PO)*one_over_ps_sq;
|
93
|
|
94
|
return 1.0 / (1.0 + 1.0/(sqrt(DOT*DOT+D*one_over_ps_sq)-DOT));
|
95
|
}
|
96
|
|
97
|
#endif // NUM_VERTEX>0
|
98
|
|
99
|
//////////////////////////////////////////////////////////////////////////////////////////////
|
100
|
|
101
|
void main()
|
102
|
{
|
103
|
vec3 v = a_Position + u_Inflate*a_Inflate;
|
104
|
vec3 n = a_Normal;
|
105
|
|
106
|
#ifdef PREAPPLY
|
107
|
vec3 inf = a_Inflate;
|
108
|
#endif
|
109
|
|
110
|
#if NUM_VERTEX>0
|
111
|
int effect=0;
|
112
|
|
113
|
for(int i=0; i<vNumEffects; i++)
|
114
|
{
|
115
|
// ENABLED EFFECTS WILL BE INSERTED HERE
|
116
|
|
117
|
effect+=3;
|
118
|
}
|
119
|
#endif
|
120
|
|
121
|
v_Position = v;
|
122
|
|
123
|
#ifdef PREAPPLY
|
124
|
v_endPosition = n;
|
125
|
v_Inflate = inf;
|
126
|
#else
|
127
|
v_endPosition = v + 0.5*n;
|
128
|
#endif
|
129
|
|
130
|
v_TexCoordinate = a_TexCoordinate;
|
131
|
v_Normal = normalize(vec3(u_MVMatrix*vec4(n,0.0)));
|
132
|
gl_Position = u_MVPMatrix*vec4(v,1.0);
|
133
|
}
|