1 |
d333eb6b
|
Leszek Koltunski
|
//////////////////////////////////////////////////////////////////////////////////////////////
|
2 |
|
|
// Copyright 2016 Leszek Koltunski //
|
3 |
|
|
// //
|
4 |
7602a827
|
Leszek Koltunski
|
// This file is part of DistortedLibrary. //
|
5 |
d333eb6b
|
Leszek Koltunski
|
// //
|
6 |
7602a827
|
Leszek Koltunski
|
// DistortedLibrary is free software: you can redistribute it and/or modify //
|
7 |
d333eb6b
|
Leszek Koltunski
|
// 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 |
7602a827
|
Leszek Koltunski
|
// DistortedLibrary is distributed in the hope that it will be useful, //
|
12 |
d333eb6b
|
Leszek Koltunski
|
// 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 |
7602a827
|
Leszek Koltunski
|
// along with DistortedLibrary. If not, see <http://www.gnu.org/licenses/>. //
|
18 |
d333eb6b
|
Leszek Koltunski
|
//////////////////////////////////////////////////////////////////////////////////////////////
|
19 |
|
|
|
20 |
341151fc
|
Leszek Koltunski
|
precision highp float;
|
21 |
c1a38ba3
|
Leszek Koltunski
|
precision highp int;
|
22 |
2e7ad49f
|
Leszek Koltunski
|
|
23 |
94f6d472
|
Leszek Koltunski
|
in vec3 a_Position; // Per-vertex position.
|
24 |
|
|
in vec3 a_Normal; // Per-vertex normal vector.
|
25 |
6f2d931d
|
Leszek Koltunski
|
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 |
94f6d472
|
Leszek Koltunski
|
in vec2 a_TexCoordinate; // Per-vertex texture coordinate.
|
28 |
6f2d931d
|
Leszek Koltunski
|
|
29 |
94f6d472
|
Leszek Koltunski
|
out vec3 v_Position; //
|
30 |
3fc9327a
|
Leszek Koltunski
|
out vec3 v_endPosition; // for Transform Feedback only
|
31 |
94f6d472
|
Leszek Koltunski
|
out vec3 v_Normal; //
|
32 |
|
|
out vec2 v_TexCoordinate; //
|
33 |
5e331bc8
|
Leszek Koltunski
|
|
34 |
f6cac1f6
|
Leszek Koltunski
|
uniform vec3 u_objD; // half of object width x half of object height X half the depth;
|
35 |
|
|
// point (0,0,0) is the center of the object
|
36 |
6a06a912
|
Leszek Koltunski
|
|
37 |
bfe2c61b
|
Leszek Koltunski
|
uniform mat4 u_MVPMatrix; // the combined model/view/projection matrix.
|
38 |
|
|
uniform mat4 u_MVMatrix; // the combined model/view matrix.
|
39 |
7a5e538a
|
Leszek Koltunski
|
uniform float u_Inflate; // how much should we inflate (>0.0) or deflate (<0.0) the mesh.
|
40 |
6a06a912
|
Leszek Koltunski
|
|
41 |
|
|
#if NUM_VERTEX>0
|
42 |
ad33f883
|
Leszek Koltunski
|
uniform int vNumEffects; // total number of vertex effects
|
43 |
15aa7d94
|
Leszek Koltunski
|
uniform int vName[NUM_VERTEX]; // their names.
|
44 |
f6cac1f6
|
Leszek Koltunski
|
uniform vec4 vUniforms[3*NUM_VERTEX];// i-th effect is 3 consecutive vec4's: [3*i], [3*i+1], [3*i+2].
|
45 |
|
|
// The first vec4 is the Interpolated values,
|
46 |
4aa38649
|
Leszek Koltunski
|
// second vec4: first float - cache, next 3: Center, the third - the Region.
|
47 |
341c803d
|
Leszek Koltunski
|
|
48 |
|
|
//////////////////////////////////////////////////////////////////////////////////////////////
|
49 |
|
|
// HELPER FUNCTIONS
|
50 |
|
|
//////////////////////////////////////////////////////////////////////////////////////////////
|
51 |
9420f2fe
|
Leszek Koltunski
|
// The trick below is the if-less version of the
|
52 |
341c803d
|
Leszek Koltunski
|
//
|
53 |
|
|
// t = dx<0.0 ? (u_objD.x-v.x) / (u_objD.x-ux) : (u_objD.x+v.x) / (u_objD.x+ux);
|
54 |
|
|
// h = dy<0.0 ? (u_objD.y-v.y) / (u_objD.y-uy) : (u_objD.y+v.y) / (u_objD.y+uy);
|
55 |
|
|
// d = min(t,h);
|
56 |
|
|
//
|
57 |
|
|
// float d = min(-ps.x/(sign(ps.x)*u_objD.x+p.x),-ps.y/(sign(ps.y)*u_objD.y+p.y))+1.0;
|
58 |
|
|
//
|
59 |
|
|
// We still have to avoid division by 0 when p.x = +- u_objD.x or p.y = +- u_objD.y (i.e on the edge of the Object)
|
60 |
|
|
// We do that by first multiplying the above 'float d' with sign(denominator1*denominator2)^2.
|
61 |
|
|
//
|
62 |
353f7580
|
Leszek Koltunski
|
// 2019-01-09: make this 3D. The trick: we want only the EDGES of the cuboid to stay constant.
|
63 |
|
|
// the interiors of the Faces move! Thus, we want the MIDDLE of the PS/(sign(PS)*u_objD+S) !
|
64 |
341c803d
|
Leszek Koltunski
|
//////////////////////////////////////////////////////////////////////////////////////////////
|
65 |
353f7580
|
Leszek Koltunski
|
// return degree of the point as defined by the object cuboid (u_objD.x X u_objD.y X u_objD.z)
|
66 |
341c803d
|
Leszek Koltunski
|
|
67 |
353f7580
|
Leszek Koltunski
|
float degree_object(in vec3 S, in vec3 PS)
|
68 |
341c803d
|
Leszek Koltunski
|
{
|
69 |
353f7580
|
Leszek Koltunski
|
vec3 ONE = vec3(1.0,1.0,1.0);
|
70 |
4aa38649
|
Leszek Koltunski
|
vec3 A = sign(PS)*u_objD + S;
|
71 |
341c803d
|
Leszek Koltunski
|
|
72 |
353f7580
|
Leszek Koltunski
|
vec3 signA = sign(A); //
|
73 |
|
|
vec3 signA_SQ = signA*signA; // div = PS/A if A!=0, 0 otherwise.
|
74 |
|
|
vec3 div = signA_SQ*PS/(A-(ONE-signA_SQ)); //
|
75 |
50be8733
|
Leszek Koltunski
|
vec3 ret = sign(u_objD)-div;
|
76 |
369ee56a
|
Leszek Koltunski
|
|
77 |
50be8733
|
Leszek Koltunski
|
float d1= ret.x-ret.y;
|
78 |
|
|
float d2= ret.y-ret.z;
|
79 |
|
|
float d3= ret.x-ret.z;
|
80 |
353f7580
|
Leszek Koltunski
|
|
81 |
50be8733
|
Leszek Koltunski
|
if( d1*d2>0.0 ) return ret.y; //
|
82 |
|
|
if( d1*d3>0.0 ) return ret.z; // return 1-middle(div.x,div.y,div.z)
|
83 |
|
|
return ret.x; // (unless size of object is 0 then 0-middle)
|
84 |
341c803d
|
Leszek Koltunski
|
}
|
85 |
|
|
|
86 |
|
|
//////////////////////////////////////////////////////////////////////////////////////////////
|
87 |
353f7580
|
Leszek Koltunski
|
// Return degree of the point as defined by the Region. Currently only supports spherical regions.
|
88 |
9420f2fe
|
Leszek Koltunski
|
//
|
89 |
|
|
// Let 'PS' be the vector from point P (the current vertex) to point S (the center of the effect).
|
90 |
353f7580
|
Leszek Koltunski
|
// Let region.xyz be the vector from point S to point O (the center point of the region sphere)
|
91 |
|
|
// Let region.w be the radius of the region sphere.
|
92 |
|
|
// (This all should work regardless if S is inside or outside of the sphere).
|
93 |
73af5285
|
Leszek Koltunski
|
//
|
94 |
353f7580
|
Leszek Koltunski
|
// Then, the degree of a point with respect to a given (spherical!) Region is defined by:
|
95 |
9420f2fe
|
Leszek Koltunski
|
//
|
96 |
353f7580
|
Leszek Koltunski
|
// If P is outside the sphere, return 0.
|
97 |
50be8733
|
Leszek Koltunski
|
// Otherwise, let X be the point where the halfline SP meets the sphere - then return |PX|/|SX|,
|
98 |
9420f2fe
|
Leszek Koltunski
|
// aka the 'degree' of point P.
|
99 |
|
|
//
|
100 |
ff8ad0a7
|
Leszek Koltunski
|
// We solve the triangle OPX.
|
101 |
9420f2fe
|
Leszek Koltunski
|
// We know the lengths |PO|, |OX| and the angle OPX, because cos(OPX) = cos(180-OPS) = -cos(OPS) = -PS*PO/(|PS|*|PO|)
|
102 |
|
|
// 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)
|
103 |
|
|
// where a = PS*PO/|PS| but we are really looking for d = |PX|/(|PX|+|PS|) = 1/(1+ (|PS|/|PX|) ) and
|
104 |
|
|
// |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.
|
105 |
341c803d
|
Leszek Koltunski
|
|
106 |
4aa38649
|
Leszek Koltunski
|
float degree_region(in vec4 region, in vec3 PS)
|
107 |
341c803d
|
Leszek Koltunski
|
{
|
108 |
4aa38649
|
Leszek Koltunski
|
vec3 PO = PS + region.xyz;
|
109 |
|
|
float D = region.w*region.w-dot(PO,PO); // D = |OX|^2 - |PO|^2
|
110 |
9420f2fe
|
Leszek Koltunski
|
|
111 |
|
|
if( D<=0.0 ) return 0.0;
|
112 |
|
|
|
113 |
341c803d
|
Leszek Koltunski
|
float ps_sq = dot(PS,PS);
|
114 |
20af7b69
|
Leszek Koltunski
|
float one_over_ps_sq = 1.0/(ps_sq-(sign(ps_sq)-1.0)); // return 1.0 if ps_sq = 0.0
|
115 |
|
|
// Important: if we want to write
|
116 |
|
|
// b = 1/a if a!=0, b=1 otherwise
|
117 |
|
|
// we need to write that as
|
118 |
|
|
// b = 1 / ( a-(sign(a)-1) )
|
119 |
|
|
// [ and NOT 1 / ( a + 1 - sign(a) ) ]
|
120 |
|
|
// because the latter, if 0<a<2^-24,
|
121 |
|
|
// will suffer from round-off error and in this case
|
122 |
|
|
// a + 1.0 = 1.0 !! so 1 / (a+1-sign(a)) = 1/0 !
|
123 |
7c227ed2
|
Leszek Koltunski
|
float DOT = dot(PS,PO)*one_over_ps_sq;
|
124 |
341c803d
|
Leszek Koltunski
|
|
125 |
9420f2fe
|
Leszek Koltunski
|
return 1.0 / (1.0 + 1.0/(sqrt(DOT*DOT+D*one_over_ps_sq)-DOT));
|
126 |
341c803d
|
Leszek Koltunski
|
}
|
127 |
|
|
|
128 |
|
|
//////////////////////////////////////////////////////////////////////////////////////////////
|
129 |
353f7580
|
Leszek Koltunski
|
// return min(degree_object,degree_region). Just like degree_region, currently only supports spheres.
|
130 |
341c803d
|
Leszek Koltunski
|
|
131 |
4aa38649
|
Leszek Koltunski
|
float degree(in vec4 region, in vec3 S, in vec3 PS)
|
132 |
341c803d
|
Leszek Koltunski
|
{
|
133 |
4aa38649
|
Leszek Koltunski
|
vec3 PO = PS + region.xyz;
|
134 |
|
|
float D = region.w*region.w-dot(PO,PO); // D = |OX|^2 - |PO|^2
|
135 |
9420f2fe
|
Leszek Koltunski
|
|
136 |
|
|
if( D<=0.0 ) return 0.0;
|
137 |
|
|
|
138 |
50be8733
|
Leszek Koltunski
|
vec3 A = sign(PS)*u_objD + S;
|
139 |
4aa38649
|
Leszek Koltunski
|
vec3 signA = sign(A);
|
140 |
|
|
vec3 signA_SQ = signA*signA;
|
141 |
|
|
vec3 div = signA_SQ*PS/(A-(vec3(1.0,1.0,1.0)-signA_SQ));
|
142 |
50be8733
|
Leszek Koltunski
|
vec3 ret = sign(u_objD)-div; // if object is flat, make ret.z 0
|
143 |
353f7580
|
Leszek Koltunski
|
|
144 |
50be8733
|
Leszek Koltunski
|
float d1= ret.x-ret.y;
|
145 |
|
|
float d2= ret.y-ret.z;
|
146 |
|
|
float d3= ret.x-ret.z;
|
147 |
|
|
float degree_object;
|
148 |
353f7580
|
Leszek Koltunski
|
|
149 |
50be8733
|
Leszek Koltunski
|
if( d1*d2>0.0 ) degree_object= ret.y; //
|
150 |
|
|
else if( d1*d3>0.0 ) degree_object= ret.z; // middle of the ret.{x,y,z} triple
|
151 |
|
|
else degree_object= ret.x; //
|
152 |
369ee56a
|
Leszek Koltunski
|
|
153 |
341c803d
|
Leszek Koltunski
|
float ps_sq = dot(PS,PS);
|
154 |
20af7b69
|
Leszek Koltunski
|
float one_over_ps_sq = 1.0/(ps_sq-(sign(ps_sq)-1.0)); // return 1.0 if ps_sq = 0.0
|
155 |
7c227ed2
|
Leszek Koltunski
|
float DOT = dot(PS,PO)*one_over_ps_sq;
|
156 |
50be8733
|
Leszek Koltunski
|
float degree_region = 1.0/(1.0 + 1.0/(sqrt(DOT*DOT+D*one_over_ps_sq)-DOT));
|
157 |
341c803d
|
Leszek Koltunski
|
|
158 |
50be8733
|
Leszek Koltunski
|
return min(degree_region,degree_object);
|
159 |
341c803d
|
Leszek Koltunski
|
}
|
160 |
|
|
|
161 |
81a0b906
|
leszek
|
#endif // NUM_VERTEX>0
|
162 |
|
|
|
163 |
6a06a912
|
Leszek Koltunski
|
//////////////////////////////////////////////////////////////////////////////////////////////
|
164 |
b2dc3c19
|
Leszek Koltunski
|
|
165 |
|
|
void main()
|
166 |
|
|
{
|
167 |
e71dd7fb
|
Leszek Koltunski
|
vec3 v = 2.0*u_objD*a_Position;
|
168 |
a8537f43
|
Leszek Koltunski
|
vec3 n = a_Normal;
|
169 |
6a06a912
|
Leszek Koltunski
|
|
170 |
e71dd7fb
|
Leszek Koltunski
|
v += (u_objD.x+u_objD.y)*u_Inflate*a_Inflate;
|
171 |
|
|
|
172 |
6a06a912
|
Leszek Koltunski
|
#if NUM_VERTEX>0
|
173 |
7cd24173
|
leszek
|
int effect=0;
|
174 |
b2b83871
|
Leszek Koltunski
|
|
175 |
6a06a912
|
Leszek Koltunski
|
for(int i=0; i<vNumEffects; i++)
|
176 |
|
|
{
|
177 |
7cd24173
|
leszek
|
// ENABLED EFFECTS WILL BE INSERTED HERE
|
178 |
b2b83871
|
Leszek Koltunski
|
|
179 |
7cd24173
|
leszek
|
effect+=3;
|
180 |
6a06a912
|
Leszek Koltunski
|
}
|
181 |
|
|
#endif
|
182 |
f80337b5
|
leszek
|
|
183 |
a8537f43
|
Leszek Koltunski
|
v_Position = v;
|
184 |
3fc9327a
|
Leszek Koltunski
|
v_endPosition = v + (0.3*u_objD.x)*n;
|
185 |
2dacdeb2
|
Leszek Koltunski
|
v_TexCoordinate = a_TexCoordinate;
|
186 |
f80337b5
|
leszek
|
v_Normal = normalize(vec3(u_MVMatrix*vec4(n,0.0)));
|
187 |
3fc9327a
|
Leszek Koltunski
|
gl_Position = u_MVPMatrix*vec4(v,1.0);
|
188 |
d333eb6b
|
Leszek Koltunski
|
}
|