Revision b2dc3c19
Added by Leszek Koltunski almost 8 years ago
src/main/res/raw/main_vertex_shader.glsl | ||
---|---|---|
214 | 214 |
// along the force line is. |
215 | 215 |
// 0<=C<1 looks completely ridiculous and C<0 destroys the system. |
216 | 216 |
|
217 |
void deform(in int effect, inout vec3 v) |
|
217 |
void deform(in int effect, inout vec3 v, inout vec3 n)
|
|
218 | 218 |
{ |
219 | 219 |
const vec2 ONE = vec2(1.0,1.0); |
220 | 220 |
|
... | ... | |
247 | 247 |
|
248 | 248 |
v.x -= (mvXvert+mvXhorz); |
249 | 249 |
v.y -= (mvYvert+mvYhorz); |
250 |
|
|
250 | 251 |
v.z += force.z*d*d*(3.0*d*d -8.0*d +6.0); // thick bubble |
252 |
float b = -(12.0*force.z*d*(1.0-d)*(1.0-d)*(1.0-d))*one_over_denom;// |
|
253 |
|
|
254 |
n.xy += n.z*b*ps; |
|
251 | 255 |
} |
252 | 256 |
|
253 | 257 |
////////////////////////////////////////////////////////////////////////////////////////////// |
254 | 258 |
// DISTORT EFFECT |
255 | 259 |
// |
256 |
// Point (Px,Py) gets moved by vector (Wx,Wy,Wz) where Wx/Wy = Vx/Vy i.e. Wx=aVx and Wy=aVy where
|
|
257 |
// a=Py/Sy (N --> when (Px,Py) is above (Sx,Sy)) or a=Px/Sx (W) or a=(w-Px)/(w-Sx) (E) or a=(h-Py)/(h-Sy) (S)
|
|
260 |
// Point (Px,Py) gets moved by vector (Wx,Wy,Wz) where Wx/Wy = Vx/Vy i.e. Wx=aVx and Wy=aVy where |
|
261 |
// a=Py/Sy (N --> when (Px,Py) is above (Sx,Sy)) or a=Px/Sx (W) or a=(w-Px)/(w-Sx) (E) or a=(h-Py)/(h-Sy) (S) |
|
258 | 262 |
// It remains to be computed which of the N,W,E or S case we have: answer: a = min[ Px/Sx , Py/Sy , (w-Px)/(w-Sx) , (h-Py)/(h-Sy) ] |
259 | 263 |
// Computations above are valid for screen (0,0)x(w,h) but here we have (-w/2,-h/2)x(w/2,h/2) |
260 |
//
|
|
264 |
// |
|
261 | 265 |
// the vertical part |
262 | 266 |
// Let |(v.x,v.y),(ux,uy)| = |PS|, ux-v.x=dx,uy-v.y=dy, f(x) (0<=x<=|SX|) be the shape of the side of the bubble. |
263 | 267 |
// H(v.x,v.y) = |PS|>|SX| ? 0 : f(|PX|) |
264 |
// N(v.x,v.y) = |PS|>|SX| ? (0,0,1) : ( -(dx/|PS|)sin(beta), -(dy/|PS|)sin(beta), cos(beta) ) where tan(beta) is f'(|PX|)
|
|
265 |
// ( i.e. normalize( dx, dy, -|PS|/f'(|PX|))
|
|
268 |
// N(v.x,v.y) = |PS|>|SX| ? (0,0,1) : ( -(dx/|PS|)sin(beta), -(dy/|PS|)sin(beta), cos(beta) ) where tan(beta) is f'(|PX|) |
|
269 |
// ( i.e. normalize( dx, dy, -|PS|/f'(|PX|)) |
|
266 | 270 |
// |
267 | 271 |
// Now we also have to take into account the effect horizontal move by V=(u_dVx[i],u_dVy[i]) will have on the normal vector. |
268 |
// Solution:
|
|
272 |
// Solution: |
|
269 | 273 |
// 1. Decompose the V into two subcomponents, one parallel to SX and another perpendicular. |
270 | 274 |
// 2. Convince yourself (draw!) that the perpendicular component has no effect on normals. |
271 | 275 |
// 3. The parallel component changes the length of |SX| by the factor of a=(|SX|-|Vpar|)/|SX| (where the length |
... | ... | |
273 | 277 |
// 4. that in turn leaves the x and y parts of the normal unchanged and multiplies the z component by a! |
274 | 278 |
// |
275 | 279 |
// |Vpar| = (u_dVx[i]*dx - u_dVy[i]*dy) / sqrt(ps_sq) = (Vx*dx-Vy*dy)/ sqrt(ps_sq) (-Vy because y is inverted) |
276 |
// a = (|SX| - |Vpar|)/|SX| = 1 - |Vpar|/((sqrt(ps_sq)/(1-d)) = 1 - (1-d)*|Vpar|/sqrt(ps_sq) = 1-(1-d)*(Vx*dx-Vy*dy)/ps_sq
|
|
280 |
// a = (|SX| - |Vpar|)/|SX| = 1 - |Vpar|/((sqrt(ps_sq)/(1-d)) = 1 - (1-d)*|Vpar|/sqrt(ps_sq) = 1-(1-d)*(Vx*dx-Vy*dy)/ps_sq |
|
277 | 281 |
// |
278 | 282 |
// Side of the bubble |
279 |
//
|
|
280 |
// choose from one of the three bubble shapes: the cone, the thin bubble and the thick bubble
|
|
281 |
// Case 1:
|
|
283 |
// |
|
284 |
// choose from one of the three bubble shapes: the cone, the thin bubble and the thick bubble |
|
285 |
// Case 1: |
|
282 | 286 |
// f(t) = t, i.e. f(x) = uz * x/|SX| (a cone) |
283 | 287 |
// -|PS|/f'(|PX|) = -|PS|*|SX|/uz but since ps_sq=|PS|^2 and d=|PX|/|SX| then |PS|*|SX| = ps_sq/(1-d) |
284 | 288 |
// so finally -|PS|/f'(|PX|) = -ps_sq/(uz*(1-d)) |
285 |
//
|
|
286 |
// Case 2:
|
|
289 |
// |
|
290 |
// Case 2: |
|
287 | 291 |
// f(t) = 3t^2 - 2t^3 --> f(0)=0, f'(0)=0, f'(1)=0, f(1)=1 (the bell curve) |
288 | 292 |
// here we have t = x/|SX| which makes f'(|PX|) = 6*uz*|PS|*|PX|/|SX|^3. |
289 | 293 |
// so -|PS|/f'(|PX|) = (-|SX|^3)/(6uz|PX|) = (-|SX|^2) / (6*uz*d) but |
290 | 294 |
// d = |PX|/|SX| and ps_sq = |PS|^2 so |SX|^2 = ps_sq/(1-d)^2 |
291 | 295 |
// so finally -|PS|/f'(|PX|) = -ps_sq/ (6uz*d*(1-d)^2) |
292 |
//
|
|
296 |
// |
|
293 | 297 |
// Case 3: |
294 | 298 |
// f(t) = 3t^4-8t^3+6t^2 would be better as this satisfies f(0)=0, f'(0)=0, f'(1)=0, f(1)=1, |
295 | 299 |
// f(0.5)=0.7 and f'(t)= t(t-1)^2 >=0 for t>=0 so this produces a fuller, thicker bubble! |
296 |
// then -|PS|/f'(|PX|) = (-|PS|*|SX)) / (12uz*d*(d-1)^2) but |PS|*|SX| = ps_sq/(1-d) (see above!)
|
|
297 |
// so finally -|PS|/f'(|PX|) = -ps_sq/ (12uz*d*(1-d)^3)
|
|
300 |
// then -|PS|/f'(|PX|) = (-|PS|*|SX)) / (12uz*d*(d-1)^2) but |PS|*|SX| = ps_sq/(1-d) (see above!) |
|
301 |
// so finally -|PS|/f'(|PX|) = -ps_sq/ (12uz*d*(1-d)^3) |
|
298 | 302 |
// |
299 | 303 |
// Now, new requirement: we have to be able to add up normal vectors, i.e. distort already distorted surfaces. |
300 | 304 |
// If a surface is given by z = f(x,y), then the normal vector at (x0,y0) is given by (-df/dx (x0,y0), -df/dy (x0,y0), 1 ). |
301 |
// so if we have two surfaces defined by f1(x,y) and f2(x,y) with their normals expressed as (f1x,f1y,1) and (f2x,f2y,1)
|
|
305 |
// so if we have two surfaces defined by f1(x,y) and f2(x,y) with their normals expressed as (f1x,f1y,1) and (f2x,f2y,1) |
|
302 | 306 |
// then the normal to g = f1+f2 is simply given by (f1x+f2x,f1y+f2y,1), i.e. if the third components are equal, then we |
303 | 307 |
// can simply add up the first and second components. |
304 | 308 |
// |
305 | 309 |
// Thus we actually want to compute N(v.x,v.y) = a*(-(dx/|PS|)*f'(|PX|), -(dy/|PS|)*f'(|PX|), 1) and keep adding |
306 | 310 |
// the first two components. (a is the horizontal part) |
307 |
|
|
308 |
void distort(in int effect, inout vec3 v) |
|
311 |
|
|
312 |
void distort(in int effect, inout vec3 v, inout vec3 n)
|
|
309 | 313 |
{ |
310 | 314 |
vec2 center = vUniforms[effect+1].yz; |
311 | 315 |
vec2 ps = center-v.xy; |
312 | 316 |
vec3 force = vUniforms[effect].xyz; |
313 | 317 |
float d = degree(vUniforms[effect+2],center,ps); |
318 |
float denom = dot(ps+(1.0-d)*force.xy,ps); |
|
319 |
float one_over_denom = 1.0/(denom-0.001*(sign(denom)-1.0)); // = denom==0 ? 1000:1/denom; |
|
320 |
|
|
321 |
//v.z += force.z*d; // cone |
|
322 |
//b = -(force.z*(1.0-d))*one_over_denom; // |
|
314 | 323 |
|
315 |
//v.z += force.z*d; // cone |
|
316 |
//v.z += force.z*d*d*(3.0-2.0*d); // thin bubble |
|
317 |
v.z += force.z*d*d*(3.0*d*d -8.0*d +6.0); // thick bubble |
|
324 |
//v.z += force.z*d*d*(3.0-2.0*d); // thin bubble |
|
325 |
//b = -(6.0*force.z*d*(1.0-d)*(1.0-d))*one_over_denom; // |
|
326 |
|
|
327 |
v.z += force.z*d*d*(3.0*d*d -8.0*d +6.0); // thick bubble |
|
328 |
float b = -(12.0*force.z*d*(1.0-d)*(1.0-d)*(1.0-d))*one_over_denom; // |
|
318 | 329 |
|
319 | 330 |
v.xy += d*force.xy; |
331 |
n.xy += n.z*b*ps; |
|
320 | 332 |
} |
321 |
|
|
333 |
|
|
322 | 334 |
////////////////////////////////////////////////////////////////////////////////////////////// |
323 | 335 |
// SINK EFFECT |
324 | 336 |
// |
325 | 337 |
// Pull P=(v.x,v.y) towards center of the effect with P' = P + (1-h)*dist(S-P) |
326 | 338 |
// when h>1 we are pushing points away from S: P' = P + (1/h-1)*dist(S-P) |
327 |
|
|
339 |
|
|
328 | 340 |
void sink(in int effect,inout vec3 v) |
329 | 341 |
{ |
330 | 342 |
vec2 center = vUniforms[effect+1].yz; |
331 | 343 |
vec2 ps = center-v.xy; |
332 | 344 |
float h = vUniforms[effect].x; |
333 | 345 |
float t = degree(vUniforms[effect+2],center,ps) * (1.0-h)/max(1.0,h); |
334 |
|
|
335 |
v.xy += t*ps;
|
|
346 |
|
|
347 |
v.xy += t*ps; |
|
336 | 348 |
} |
337 | 349 |
|
338 | 350 |
////////////////////////////////////////////////////////////////////////////////////////////// |
... | ... | |
360 | 372 |
// SWIRL EFFECT |
361 | 373 |
// |
362 | 374 |
// Let d be the degree of the current vertex V with respect to center of the effect S and Region vRegion. |
363 |
// This effect rotates the current vertex V by vInterpolated.x radians clockwise around the circle dilated
|
|
375 |
// This effect rotates the current vertex V by vInterpolated.x radians clockwise around the circle dilated |
|
364 | 376 |
// by (1-d) around the center of the effect S. |
365 | 377 |
|
366 | 378 |
void swirl(in int effect, inout vec3 v) |
... | ... | |
448 | 460 |
// |
449 | 461 |
// Generally speaking I'd keep to amplitude < length, as the opposite case has some other problems as well. |
450 | 462 |
|
451 |
void wave(in int effect, inout vec3 v) |
|
463 |
void wave(in int effect, inout vec3 v, inout vec3 n)
|
|
452 | 464 |
{ |
453 | 465 |
vec2 center = vUniforms[effect+1].yz; |
454 | 466 |
float amplitude = vUniforms[effect ].x; |
... | ... | |
473 | 485 |
vec3 dir= vec3(sinB*cosA,cosB*cosA,sinA); |
474 | 486 |
|
475 | 487 |
v += sin(angle)*deg*dir; |
488 |
|
|
489 |
if( n.z != 0.0 ) |
|
490 |
{ |
|
491 |
float sqrtX = sqrt(dir.y*dir.y + dir.z*dir.z); |
|
492 |
float sqrtY = sqrt(dir.x*dir.x + dir.z*dir.z); |
|
493 |
|
|
494 |
float sinX = ( sqrtY==0.0 ? 0.0 : dir.z / sqrtY); |
|
495 |
float cosX = ( sqrtY==0.0 ? 1.0 : dir.x / sqrtY); |
|
496 |
float sinY = ( sqrtX==0.0 ? 0.0 : dir.z / sqrtX); |
|
497 |
float cosY = ( sqrtX==0.0 ? 1.0 : dir.y / sqrtX); |
|
498 |
|
|
499 |
float abs_z = dir.z <0.0 ? -(sinX*sinY) : (sinX*sinY); |
|
500 |
|
|
501 |
float tmp = 1.578*cos(angle)*deg/length; |
|
502 |
|
|
503 |
float fx =-cosB*tmp; |
|
504 |
float fy = sinB*tmp; |
|
505 |
|
|
506 |
vec3 sx = vec3 (1.0+cosX*fx,cosY*sinX*fx,abs_z*fx); |
|
507 |
vec3 sy = vec3 (cosX*sinY*fy,1.0+cosY*fy,abs_z*fy); |
|
508 |
|
|
509 |
vec3 normal = cross(sx,sy); |
|
510 |
|
|
511 |
if( normal.z<=0.0 ) // Why this bizarre shit rather than the straightforward |
|
512 |
{ // |
|
513 |
normal.x= 0.0; // if( normal.z>0.0 ) |
|
514 |
normal.y= 0.0; // { |
|
515 |
normal.z= 1.0; // n.x = (n.x*normal.z + n.z*normal.x); |
|
516 |
} // n.y = (n.y*normal.z + n.z*normal.y); |
|
517 |
// n.z = (n.z*normal.z); |
|
518 |
// } |
|
519 |
n.x = (n.x*normal.z + n.z*normal.x); // |
|
520 |
n.y = (n.y*normal.z + n.z*normal.y); // ? Because if we do the above, my shitty Nexus4 crashes |
|
521 |
n.z = (n.z*normal.z); // during shader compilation! |
|
522 |
} |
|
476 | 523 |
} |
477 | 524 |
} |
478 | 525 |
|
479 | 526 |
#endif |
480 | 527 |
|
481 | 528 |
////////////////////////////////////////////////////////////////////////////////////////////// |
482 |
|
|
483 |
void main()
|
|
484 |
{
|
|
529 |
|
|
530 |
void main() |
|
531 |
{ |
|
485 | 532 |
vec3 v = 2.0*u_objD*a_Position; |
486 | 533 |
vec3 n = a_Normal; |
487 | 534 |
|
488 | 535 |
#if NUM_VERTEX>0 |
489 |
|
|
490 |
vec3 b1; |
|
491 |
float len = n.x*n.x+n.y*n.y; |
|
492 |
float l = u_objD.x / 2.0; |
|
493 |
|
|
494 |
if( len>0.0 ) |
|
495 |
{ |
|
496 |
len = sqrt(len); |
|
497 |
b1 = vec3( n.y/len,-n.x/len,0.0); |
|
498 |
} |
|
499 |
else |
|
500 |
{ |
|
501 |
b1 = vec3(1.0,0.0,0.0); |
|
502 |
} |
|
503 |
|
|
504 |
vec3 b2 = cross(n,b1); |
|
505 |
vec3 v1 = v+b1; |
|
506 |
vec3 v2 = v+b2; |
|
507 |
|
|
508 | 536 |
int j=0; |
509 | 537 |
|
510 | 538 |
for(int i=0; i<vNumEffects; i++) |
511 | 539 |
{ |
512 |
if( vType[i]==DISTORT) |
|
513 |
{ |
|
514 |
distort(j,v); |
|
515 |
distort(j,v1); |
|
516 |
distort(j,v2); |
|
517 |
} |
|
518 |
else if( vType[i]==DEFORM ) |
|
519 |
{ |
|
520 |
deform (j,v); |
|
521 |
deform (j,v1); |
|
522 |
deform (j,v2); |
|
523 |
} |
|
524 |
else if( vType[i]==SINK ) |
|
525 |
{ |
|
526 |
sink (j,v); |
|
527 |
sink (j,v1); |
|
528 |
sink (j,v2); |
|
529 |
} |
|
530 |
else if( vType[i]==PINCH ) |
|
531 |
{ |
|
532 |
pinch (j,v); |
|
533 |
pinch (j,v1); |
|
534 |
pinch (j,v2); |
|
535 |
} |
|
536 |
else if( vType[i]==SWIRL ) |
|
537 |
{ |
|
538 |
swirl (j,v); |
|
539 |
swirl (j,v1); |
|
540 |
swirl (j,v2); |
|
541 |
} |
|
542 |
else if( vType[i]==WAVE ) |
|
543 |
{ |
|
544 |
wave (j,v); |
|
545 |
wave (j,v1); |
|
546 |
wave (j,v2); |
|
547 |
} |
|
540 |
if( vType[i]==DISTORT) distort(j,v,n); |
|
541 |
else if( vType[i]==DEFORM ) deform (j,v,n); |
|
542 |
else if( vType[i]==SINK ) sink (j,v); |
|
543 |
else if( vType[i]==PINCH ) pinch (j,v); |
|
544 |
else if( vType[i]==SWIRL ) swirl (j,v); |
|
545 |
else if( vType[i]==WAVE ) wave (j,v,n); |
|
548 | 546 |
|
549 | 547 |
j+=3; |
550 | 548 |
} |
551 | 549 |
|
552 |
n = cross(v1-v,v2-v); |
|
553 |
|
|
554 | 550 |
restrictZ(v.z); |
555 | 551 |
#endif |
556 | 552 |
|
Also available in: Unified diff
Back out the last change.