Revision b2dc3c19
Added by Leszek Koltunski over 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.