thecodewarrior

Sparkle particle OpenGL

Jul 14th, 2016
103
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.86 KB | None | 0 0
  1. const float PI = 3.14159;
  2. int randID = 0;
  3.  
  4. uniform float time;
  5.  
  6. uniform int fanCount;
  7. uniform float fanSpeedMax;
  8. uniform float fanSpeedMin;
  9. uniform float fanSizeMin;
  10. uniform float fanSizeMax;
  11. uniform float fanJitterMin;
  12. uniform float fanJitterMax;
  13. uniform int fanBladesMin;
  14. uniform int fanBladesMax;
  15.  
  16.  
  17. // the current time in seconds
  18. float timeSec() {
  19.     return time;
  20. }
  21.  
  22. vec4 glColor() {
  23.     return gl_Color;
  24. }
  25.  
  26. // ======== begin platform-independant code
  27.  
  28. // gets the angle given a uv position
  29. float getUVangle(vec2 uv) {
  30.     return atan(uv.x, -uv.y) + PI;
  31.     // +PI because the result is from -pi to +pi. I want it from 0 to 2*pi
  32. }
  33.  
  34. // rand
  35. float rand(vec2 n) {
  36.     return fract(sin(dot(n, vec2(12.9898, 4.1414))) * 43758.5453);
  37. }
  38.  
  39. // noise
  40. float noise(vec2 p){
  41.     vec2 ip = floor(p);
  42.     vec2 u = fract(p);
  43.     u = u*u*(3.0-2.0*u);
  44.  
  45.     float res = mix(
  46.         mix(rand(ip),rand(ip+vec2(1.0,0.0)),u.x),
  47.         mix(rand(ip+vec2(0.0,1.0)),rand(ip+vec2(1.0,1.0)),u.x),u.y);
  48.     return res*res;
  49. }
  50.  
  51. // interpolates between two values using the control input
  52. float range(float low, float high, float control) {
  53.     return low + control * (high-low);
  54. }
  55.  
  56. // gets a random number for a fan
  57. float fanRand(int fan, int offset, float param) {
  58.     return rand(vec2(float(fan), float(offset + 100*randID) + param));
  59. }
  60.  
  61. // gets the angle offset of the fan
  62. float getFanRotation(int fanID) {
  63.     float speed  = range(fanSpeedMin*2.*PI, fanSpeedMax*2.*PI, fanRand(fanID, 10, 0.));
  64.     float initial = range(0., 2.*PI, fanRand(fanID, 11, 0.));
  65.    
  66.     return initial + speed * timeSec();
  67. }
  68.  
  69. int getBladeCount(int fanID) {
  70.     return int(range(float(fanBladesMin), float(fanBladesMax), fanRand(fanID, 30, 0.)));
  71. }
  72.  
  73. // gets the length of the fan given an angle and an index
  74. float getFanLength(int fanID, float angle) {
  75.     float bladeSweep = (2.*PI)/float(getBladeCount(fanID));
  76.     int bladeNum = int(angle/bladeSweep);
  77.     float main = range(fanSizeMin, fanSizeMax, fanRand(fanID, 20, float(bladeNum)));
  78.    
  79.     float jitter = range(fanJitterMin, fanJitterMax,
  80.                          rand(vec2( float(int(degrees(angle))  ), 0 ))
  81.                         );
  82.     return main + jitter;
  83. }
  84.  
  85. // -2 to 2 along the blade area. -1 to 1 is the area with the blade
  86. float getFanBladeCurveCoord(int fanID, float angle) {
  87.     float bladeSweep = (2.*PI)/float(getBladeCount(fanID)*2);
  88.     float bladeAngle = mod(angle, bladeSweep*2.);
  89.     return (( bladeAngle / bladeSweep )-1.)*2.;
  90. }
  91.  
  92. vec4 particle(vec2 uv) {
  93.     uv = uv - vec2(0.5);
  94.     uv = uv * 2.;
  95.     vec4 color = vec4(0);
  96.    
  97.     float uvRadius = sqrt( uv.x * uv.x + uv.y * uv.y );
  98.     float angle = getUVangle(uv);
  99.    
  100.     for(int i = 0; i < fanCount; i++) {
  101.         // the angle relative to the fan
  102.         float fanAngle = mod( angle + getFanRotation(i), 2.*PI);
  103.         // the length of the fan
  104.         float fanLength = getFanLength(i, fanAngle);
  105.         // the percent of the blade. -1 to 1 is the blade
  106.         // the rest is blank space between the blades
  107.         float fanBladeCurveCoord = getFanBladeCurveCoord(i, fanAngle);
  108.        
  109.         float w = 1.;
  110.        
  111.         // the sideways blade fading
  112.         w *= 1.-clamp(pow(fanBladeCurveCoord, 4.), 0., 1.);
  113.         // the length wise fading
  114.         w *= clamp(pow(1.-clamp(uvRadius/fanLength, 0., 1.), 1./3.), 0., 1.);
  115.        
  116.         // set the alpha
  117.         color.w = max(w, color.w);
  118.     }
  119.    
  120.     float w = color.w;
  121.    
  122.     color = mix(vec4(1), glColor(), clamp(uvRadius*2., 0., 1.));
  123.    
  124.     color.w = w * glColor().w;
  125.    
  126.     return color;
  127. }
  128.  
  129. // ======== end platform-independant code
  130.  
  131. void main()
  132. {
  133.     vec2 uv = vec2(gl_TexCoord[0]);
  134.     if(uv.x > 1.) {
  135.         randID = int(uv.x);
  136.         uv.x = fract(uv.x);
  137.     }
  138.     vec4 c = particle(uv);
  139.     gl_FragColor = c;//mix(vec4(0,0,0,1), c, c.w);
  140. }
Advertisement
Add Comment
Please, Sign In to add comment