Project

General

Profile

« Previous | Next » 

Revision 73af5285

Added by Leszek Koltunski over 7 years ago

Now we can add up the WAVE effect to others with smooth shading! Remaining issues:

- when angle A < 0, the shades are wrong
- sometimes (check with the 3D vertex & Fragment effects' app) we get black spots at seemingly random points. Looks like computational instability again.

View differences:

src/main/res/raw/main_vertex_shader.glsl
78 78
//////////////////////////////////////////////////////////////////////////////////////////////
79 79
// Return degree of the point as defined by the Region. Currently only supports circular regions.
80 80
//
81
// Let us first introduce some notation.
81 82
// Let 'PS' be the vector from point P (the current vertex) to point S (the center of the effect).
82
// Should work regardless if S is inside or outside of the circle.
83 83
// Let region.xy be the vector from point S to point O (the center point of the region circle)
84 84
// Let region.z be the radius of the region circle.
85
// (This all should work regardless if S is inside or outside of the circle).
86
//
87
// Then, the degree of a point with respect to a given (circular!) Region is defined by:
85 88
//
86 89
// If P is outside the circle, return 0.
87
// Otherwise, let X be the point where the halfline SP meets the region circle - return |PX|/||SX|,
90
// Otherwise, let X be the point where the halfline SP meets the region circle - then return |PX|/||SX|,
88 91
// aka the 'degree' of point P.
89 92
//
90 93
// We solve the triangle OPX.
......
267 270
// so finally -|PS|/f'(|PX|) = -ps_sq/ (6uz*d*(1-d)^2)
268 271
//                  
269 272
// Case 3:
270
// f(t) = 3t^4-8t^3+6t^2 would be better as this safisfies f(0)=0, f'(0)=0, f'(1)=0, f(1)=1,
273
// 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,
271 274
// f(0.5)=0.7 and f'(t)= t(t-1)^2 >=0 for t>=0 so this produces a fuller, thicker bubble!
272 275
// then -|PS|/f'(|PX|) = (-|PS|*|SX)) / (12uz*d*(d-1)^2) but |PS|*|SX| = ps_sq/(1-d) (see above!) 
273 276
// so finally -|PS|/f'(|PX|) = -ps_sq/ (12uz*d*(1-d)^3)  
274 277
//
275 278
// Now, new requirement: we have to be able to add up normal vectors, i.e. distort already distorted surfaces.
276
// 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 ).
279
// 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 ).
277 280
// 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) 
278
// then the normal to g = f1+f2 is simply given by (f1x+f2x,f1y+f2y,1), i.e. if the third component is 1, then we can simply
279
// add up the first and second components.
281
// 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
282
// can simply add up the first and second components.
280 283
//
281 284
// Thus we actually want to compute N(v.x,v.y) = a*(-(dx/|PS|)*f'(|PX|), -(dy/|PS|)*f'(|PX|), 1) and keep adding
282 285
// the first two components. (a is the horizontal part)
......
346 349
// WAVE EFFECT
347 350
//
348 351
// Directional sinusoidal wave effect.
352
//
353
// This is an effect from a (hopefully!) generic family of effects of the form (vec3 V: |V|=1 , f(x,y) )  (*)
354
// i.e. effects defined by a unit vector and an arbitrary function. Those effects are defined to move each
355
// point (x,y,0) of the XY plane to the point (x,y,0) + V*f(x,y).
356
//
357
// In this case V is defined by angles A and B (sines and cosines of which are precomputed in
358
// EffectQueueVertex and passed in the uniforms).
359
// Let's move V to start at the origin O, let point C be the endpoint of V, and let C' be C's projection
360
// to the XY plane. Then A is defined to be the angle C0C' and angle B is the angle C'O(axisY).
361
//
362
// Also, in this case f(x,y) = amplitude*sin(x/length), with those 2 parameters passed in uniforms.
363
//
364
////////////////////////////////////////////////////////
365
// How to compute any generic effect of type (*)
366
////////////////////////////////////////////////////////
367
//
368
// By definition, the vertices move by f(x,y)*V.
369
//
370
// Normals are much more complicated.
371
// Let angle X be the angle (0,Vy,Vz)((0,Vy,0)(Vx,Vy,Vz).
372
// Let angle Y be the angle (Vx,0,Vz)((Vx,0,0)(Vx,Vy,Vz).
373
//
374
// Then it can be shown that the resulting surface, at point to which point (x0,y0,0) got moved to,
375
// has 2 tangent vectors given by
376
//
377
// SX = (1.0+cosX*fx , cosY*sinX*fx , sinY*sinX*fx);  (**)
378
// SY = (cosX*sinY*fy , 1.0+cosY*fy , sinX*sinY*fy);  (***)
379
//
380
// and then obviously the normal N is given by N= SX x SY .
381
//
382
// We still need to remember the note from the distort function about adding up normals:
383
// we first need to 'normalize' the normals to make their third components equal, and then we
384
// simply add up the first and the second component while leaving the third unchanged.
385
//
386
// How to see facts (**) and (***) ? Briefly:
387
// a) compute the 2D analogon and conclude that in this case the tangent SX is given by
388
//    SX = ( cosA*f'(x) +1, sinA*f'(x) )    (where A is the angle vector V makes with X axis )
389
// b) cut the resulting surface with plane P which
390
//    - includes vector V
391
//    - crosses plane XY along line parallel to X axis
392
// c) apply the 2D analogon and notice that the tangent vector to the curve that is the common part of P
393
//    and our surface (I am talking about the tangent vector which belongs to P) is given by
394
//    (1+cosX*fx,0,sinX*fx) rotated by angle Y (where angles X,Y are defined above) along vector (1,0,0).
395
// d) compute the above and see that this is equal precisely to SX from (**).
396
// e) repeat points b,c,d in direction Y and come up with (***).
349 397

  
350 398
void wave(in int effect, inout vec4 v, inout vec4 n)
351 399
  {
......
363 411
    float sinB = vUniforms[effect  ].w;
364 412
    float cosB = vUniforms[effect+1].y;
365 413

  
366
    float angle= 1.578*(-ps.x*cosB-ps.y*sinB) / length;  // -ps.x and -ps.y becuase the 'ps=center-v.xy' inverts the XY axis!
414
    float angle= 1.578*(-ps.x*cosB-ps.y*sinB) / length;  // -ps.x and -ps.y because the 'ps=center-v.xy' inverts the XY axis!
367 415
    vec3 dir   = vec3(sinB*cosA,cosB*cosA,sinA);
368 416

  
369 417
    v.xyz += sin(angle)*deg*dir;
370 418

  
371
    float sqrtX = sqrt(dir.y*dir.y + dir.z*dir.z);
372
    float sqrtY = sqrt(dir.x*dir.x + dir.z*dir.z);
419
    if( n.z != 0.0 )
420
      {
421
      float sqrtX = sqrt(dir.y*dir.y + dir.z*dir.z);
422
      float sqrtY = sqrt(dir.x*dir.x + dir.z*dir.z);
373 423

  
374
    float sinX = ( sqrtY==0.0 ? 0.0 : dir.z / sqrtY);
375
    float cosX = ( sqrtY==0.0 ? 1.0 : dir.x / sqrtY);
376
    float sinY = ( sqrtX==0.0 ? 0.0 : dir.z / sqrtX);
377
    float cosY = ( sqrtX==0.0 ? 1.0 : dir.y / sqrtX);
424
      float sinX = ( sqrtY==0.0 ? 0.0 : dir.z / sqrtY);
425
      float cosX = ( sqrtY==0.0 ? 1.0 : dir.x / sqrtY);
426
      float sinY = ( sqrtX==0.0 ? 0.0 : dir.z / sqrtX);
427
      float cosY = ( sqrtX==0.0 ? 1.0 : dir.y / sqrtX);
378 428

  
379
    float tmp = 1.578*cos(angle)*deg/length;
429
      float tmp = 1.578*cos(angle)*deg/length;
380 430

  
381
    float fx = cosB*tmp;
382
    float fy = sinB*tmp;
431
      float fx = cosB*tmp;
432
      float fy = sinB*tmp;
383 433

  
384
    vec3 sx = vec3 (1.0+cosX*fx,cosY*sinX*fx,sinY*sinX*fx);
385
    vec3 sy = vec3 (cosX*sinY*fy,1.0+cosY*fy,sinX*sinY*fy);
434
      vec3 sx = vec3 (1.0+cosX*fx,cosY*sinX*fx,sinY*sinX*fx);
435
      vec3 sy = vec3 (cosX*sinY*fy,1.0+cosY*fy,sinX*sinY*fy);
386 436

  
387
    vec3 normal = cross(sx,sy);
437
      vec3 normal = cross(sx,sy);
388 438

  
389
    if( n.z != 0.0 )
390
      {
391
      n.xyz = n.z*normal;
439
      if( normal.z > 0.0 )
440
        {
441
        n.xy += (n.z/normal.z)*vec2(normal.x,normal.y);
442
        }
392 443
      }
393 444
    }
394 445
  }

Also available in: Unified diff