Project

General

Profile

« Previous | Next » 

Revision b2dc3c19

Added by Leszek Koltunski over 7 years ago

Back out the last change.

View differences:

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