vortexVertexShader.glsl 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
  2. /*
  3. * This file is part of the LibreOffice project.
  4. *
  5. * This Source Code Form is subject to the terms of the Mozilla Public
  6. * License, v. 2.0. If a copy of the MPL was not distributed with this
  7. * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  8. */
  9. #version 150
  10. #define M_PI 3.1415926535897932384626433832795
  11. in vec3 a_position;
  12. in vec3 a_normal;
  13. in vec2 a_texCoord;
  14. in float tileInfo;
  15. uniform mat4 u_modelViewMatrix;
  16. uniform mat4 u_sceneTransformMatrix;
  17. uniform mat4 u_primitiveTransformMatrix;
  18. uniform mat4 u_operationsTransformMatrix;
  19. uniform float time;
  20. uniform ivec2 numTiles;
  21. uniform sampler2D permTexture;
  22. uniform float slide;
  23. // Workaround for Intel's Windows driver, to prevent optimisation breakage.
  24. uniform float zero;
  25. out vec2 g_texturePosition;
  26. out vec3 g_normal;
  27. out mat4 modelViewMatrix;
  28. out mat4 transform;
  29. out float nTime;
  30. out float startTime;
  31. out float endTime;
  32. float snoise(vec2 p)
  33. {
  34. return texture(permTexture, p).r;
  35. }
  36. mat4 identityMatrix(void)
  37. {
  38. return mat4(1.0, 0.0, 0.0, 0.0,
  39. 0.0, 1.0, 0.0, 0.0,
  40. 0.0, 0.0, 1.0, 0.0,
  41. 0.0, 0.0, 0.0, 1.0);
  42. }
  43. mat4 translationMatrix(vec3 axis)
  44. {
  45. mat4 matrix = identityMatrix();
  46. matrix[3] = vec4(axis, 1.0);
  47. return matrix;
  48. }
  49. mat4 rotationMatrix(vec3 axis, float angle)
  50. {
  51. axis = normalize(axis);
  52. float s = sin(angle);
  53. float c = cos(angle);
  54. float oc = 1.0 - c;
  55. return mat4(oc * axis.x * axis.x + c, oc * axis.x * axis.y - axis.z * s, oc * axis.z * axis.x + axis.y * s, 0.0,
  56. oc * axis.x * axis.y + axis.z * s, oc * axis.y * axis.y + c, oc * axis.y * axis.z - axis.x * s, 0.0,
  57. oc * axis.z * axis.x - axis.y * s, oc * axis.y * axis.z + axis.x * s, oc * axis.z * axis.z + c, 0.0,
  58. 0.0, 0.0, 0.0, 1.0);
  59. }
  60. void main( void )
  61. {
  62. // Each tile moves during only half of the transition. The leftmost
  63. // tiles start moving at the start and arrive at their end
  64. // position around time=0.5, when the tiles there (the rightmost
  65. // ones) start moving. (The exact time each tile is moving is
  66. // fuzzed a bit to make a more random appearance.)
  67. // In GLSL 1.20 we don't have any bitwise operators, sigh
  68. int tileXIndex = int(mod(int(tileInfo), 256));
  69. int tileYIndex = int(mod(int(tileInfo) / 256, 256));
  70. // A semi-random number 0..1, different for neighbouring tiles, to know when they should start moving.
  71. float startTimeFuzz = snoise(vec2(float(tileXIndex)/(numTiles.x-1), float(tileYIndex)/(numTiles.y-1)));
  72. // A semi-random number -1.5..1.5, different for neighbouring tiles, to specify their rotation center.
  73. // The additional 0.5 on each side is because we want some tiles to rotate outside.
  74. float rotationFuzz = snoise(vec2(float(numTiles.x + tileXIndex)/(numTiles.x-1), float(tileYIndex)/(numTiles.y-1))) * 3.0 - 1.5;
  75. startTime = float(tileXIndex)/(numTiles.x-1) * 0.2 + startTimeFuzz * 0.2;
  76. endTime = min(startTime + 0.7, 1.0);
  77. bool isLeavingSlide = (slide < 0.5);
  78. const vec4 invalidPosition = vec4(-256.0, -256.0, -256.0, -256.0);
  79. // Don’t display the tile before or after its rotation, depending on the slide.
  80. if (!isLeavingSlide)
  81. {
  82. if (time < max(0.3, startTime))
  83. {
  84. gl_Position = invalidPosition;
  85. return;
  86. }
  87. nTime = 1.0 - time;
  88. }
  89. else
  90. {
  91. if (time > endTime)
  92. {
  93. gl_Position = invalidPosition;
  94. return;
  95. }
  96. nTime = time;
  97. }
  98. transform = identityMatrix();
  99. if (nTime > startTime && nTime <= endTime)
  100. {
  101. // We are in the rotation part.
  102. float rotation = (nTime - startTime) / (endTime - startTime);
  103. if (isLeavingSlide)
  104. rotation *= -1.0;
  105. if (rotation < -0.5 || rotation > 0.5) {
  106. gl_Position = invalidPosition;
  107. return;
  108. }
  109. // Translation vector to set the origin of the rotation.
  110. vec3 translationVector = vec3(rotationFuzz, 0.0, 0.0);
  111. // Compute the actual rotation matrix.
  112. // Intel's Windows driver gives a wrong matrix when all operations are done at once.
  113. if (zero < 1.0)
  114. transform = translationMatrix(translationVector) * transform;
  115. if (zero < 2.0)
  116. transform = rotationMatrix(vec3(0.0, 1.0, 0.0), clamp(rotation, -1.0, 1.0) * M_PI) * transform;
  117. if (zero < 3.0)
  118. transform = translationMatrix(-translationVector) * transform;
  119. }
  120. modelViewMatrix = u_modelViewMatrix * u_operationsTransformMatrix * u_sceneTransformMatrix * u_primitiveTransformMatrix;
  121. gl_Position = vec4(a_position, 1.0);
  122. g_texturePosition = a_texCoord;
  123. g_normal = a_normal;
  124. }
  125. /* vim:set shiftwidth=4 softtabstop=4 expandtab: */