tile-flip.vs 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. /*
  2. * Copyright (c)2012 Adobe Systems Incorporated. All rights reserved.
  3. * Copyright (c)2012 Branislav Ulicny
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. */
  17. precision mediump float;
  18. // Built-in attributes
  19. attribute vec4 a_position;
  20. attribute vec2 a_texCoord;
  21. attribute vec3 a_triangleCoord;
  22. // Built-in uniforms
  23. uniform mat4 u_projectionMatrix;
  24. uniform vec2 u_meshSize;
  25. uniform vec2 u_textureSize;
  26. // Uniform passed in from CSS
  27. uniform mat4 transform;
  28. uniform float amount;
  29. uniform float randomness;
  30. uniform vec3 flipAxis;
  31. // Varyings
  32. varying float v_depth;
  33. varying vec2 v_uv;
  34. // Constants
  35. const float PI2 = 1.5707963267948966;
  36. // Create perspective matrix
  37. mat4 perspectiveMatrix(float p)
  38. {
  39. float perspective = - 1.0 / p;
  40. return mat4(
  41. 1.0, 0.0, 0.0, 0.0,
  42. 0.0, 1.0, 0.0, 0.0,
  43. 0.0, 0.0, 1.0, perspective,
  44. 0.0, 0.0, 0.0, 1.0
  45. );
  46. }
  47. // Rotate vector
  48. vec3 rotateVectorByQuaternion(vec3 v, vec4 q)
  49. {
  50. vec3 dest = vec3(0.0);
  51. float x = v.x, y = v.y, z = v.z;
  52. float qx = q.x, qy = q.y, qz = q.z, qw = q.w;
  53. // Calculate quaternion * vector.
  54. float ix = qw * x + qy * z - qz * y,
  55. iy = qw * y + qz * x - qx * z,
  56. iz = qw * z + qx * y - qy * x,
  57. iw = -qx * x - qy * y - qz * z;
  58. // Calculate result * inverse quaternion.
  59. dest.x = ix * qw + iw * -qx + iy * -qz - iz * -qy;
  60. dest.y = iy * qw + iw * -qy + iz * -qx - ix * -qz;
  61. dest.z = iz * qw + iw * -qz + ix * -qy - iy * -qx;
  62. return dest;
  63. }
  64. // Convert rotation.
  65. vec4 axisAngleToQuaternion(vec3 axis, float angle)
  66. {
  67. vec4 dest = vec4(0.0);
  68. float halfAngle = angle / 2.0;
  69. float s = sin(halfAngle);
  70. dest.x = axis.x * s;
  71. dest.y = axis.y * s;
  72. dest.z = axis.z * s;
  73. dest.w = cos(halfAngle);
  74. return dest;
  75. }
  76. // Random function based on the tile coordinate.
  77. // This will return the same value for all the vertices in the same tile (i.e. two triangles).
  78. float random(vec2 scale)
  79. {
  80. // Use the fragment position as a different seed per-pixel.
  81. return fract(sin(dot(vec2(a_triangleCoord.x, a_triangleCoord.y), scale)) * 4000.0);
  82. }
  83. // Main
  84. void main()
  85. {
  86. // FIXME: We must swap x and y as a workaround for:
  87. // https://bugs.webkit.org/show_bug.cgi?id=96285
  88. vec2 u_meshSize = u_meshSize.yx;
  89. vec4 pos = a_position;
  90. float aspect = u_textureSize.x / u_textureSize.y;
  91. float cx = a_triangleCoord.x / u_meshSize.y - 0.5 + 0.5 / u_meshSize.y;
  92. float cy = a_triangleCoord.y / u_meshSize.x - 0.5 + 0.5 / u_meshSize.x;
  93. vec3 centroid = vec3(cx, cy, 0.0);
  94. float r = random(vec2(10.0, 80.0));
  95. float rr = mix(0.0, PI2, amount * (1.0 + randomness * r));
  96. vec4 rotation = vec4(flipAxis, rr);
  97. vec4 qRotation = axisAngleToQuaternion(normalize(rotation.xyz), rotation.w);
  98. vec3 newPosition = rotateVectorByQuaternion((pos.xyz - centroid)* vec3(aspect, 1., 1.0), qRotation) * vec3(1.0 / aspect, 1.0, 1.0) + centroid;
  99. pos.xyz = newPosition;
  100. gl_Position = u_projectionMatrix * transform * pos;
  101. // Pass varyings to the fragment shader.
  102. v_depth = abs(rr)/ PI2;
  103. v_uv = a_texCoord;
  104. }