選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

148 行
3.5 KiB

  1. [vert.glsl]
  2. #version 130
  3. in vec2 in_position;
  4. uniform float u_time;
  5. out vec4 pass_position;
  6. out vec3 water[4];
  7. out vec3 fire[4];
  8. float mod289(float x)
  9. {
  10. return x - floor(x * (1.0 / 289.0)) * 289.0;
  11. }
  12. void main(void)
  13. {
  14. mat3 r = mat3(0.36, 0.48, -0.8, -0.8, 0.60, 0.0, 0.48, 0.64, 0.60);
  15. vec3 p_pos = r * vec3(in_position * vec2(16.0, 9.0), 0.0);
  16. vec3 p_time = r * vec3(0.0, 0.0, u_time * 2.0);
  17. /* Noise sampling points for water */
  18. water[0] = p_pos / 2.0 + p_time;
  19. water[1] = p_pos / 4.0 + p_time;
  20. water[2] = p_pos / 8.0 + p_time;
  21. water[3] = p_pos / 16.0 + p_time;
  22. /* Noise sampling points for fire */
  23. p_pos = 16.0 * p_pos - r * vec3(0.0, mod289(u_time) * 128.0, 0.0);
  24. fire[0] = p_pos / 2.0 + p_time * 2.0;
  25. fire[1] = p_pos / 4.0 + p_time * 1.5;
  26. fire[2] = p_pos / 8.0 + p_time;
  27. fire[3] = p_pos / 16.0 + p_time;
  28. /* Pass rotated screen coordinates */
  29. pass_position.xy = in_position;
  30. mat2 rot = mat2(cos(u_time), sin(u_time), -sin(u_time), cos(u_time));
  31. pass_position.zw = rot * in_position;
  32. gl_Position = vec4(in_position, 0.0, 1.0);
  33. }
  34. [frag.glsl]
  35. #version 130
  36. #if defined GL_ES
  37. precision highp float;
  38. #endif
  39. in vec4 pass_position;
  40. in vec3 water[4];
  41. in vec3 fire[4];
  42. uniform float u_time;
  43. vec4 mod289(vec4 x)
  44. {
  45. return x - floor(x * (1.0 / 289.0)) * 289.0;
  46. }
  47. vec4 perm(vec4 x)
  48. {
  49. return mod289(((x * 34.0) + 1.0) * x);
  50. }
  51. float noise3d(vec3 p)
  52. {
  53. vec3 a = floor(p);
  54. vec3 d = p - a;
  55. d = d * d * (3.0 - 2.0 * d);
  56. vec4 b = a.xxyy + vec4(0.0, 1.0, 0.0, 1.0);
  57. vec4 k1 = perm(b.xyxy);
  58. vec4 k2 = perm(k1.xyxy + b.zzww);
  59. vec4 c = k2 + a.zzzz;
  60. vec4 k3 = perm(c);
  61. vec4 k4 = perm(c + 1.0);
  62. vec4 o1 = fract(k3 * (1.0 / 41.0));
  63. vec4 o2 = fract(k4 * (1.0 / 41.0));
  64. vec4 o3 = o2 * d.z + o1 * (1.0 - d.z);
  65. vec2 o4 = o3.yw * d.x + o3.xz * (1.0 - d.x);
  66. return o4.y * d.y + o4.x * (1.0 - d.y);
  67. }
  68. void main(void)
  69. {
  70. /* Dither the transition between water and fire */
  71. float test = pass_position.z * pass_position.w + 1.5 * sin(u_time);
  72. vec2 d = vec2(16.0, 9.0) * pass_position.xy;
  73. test += 0.5 * (length(fract(d) - 0.5) - length(fract(d + 0.5) - 0.5));
  74. /* Compute 4 octaves of noise */
  75. #if defined GL_ES
  76. vec4 n = vec4(noise3d((test > 0.0) ? fire[0] : water[0]),
  77. noise3d((test > 0.0) ? fire[1] : water[1]),
  78. noise3d((test > 0.0) ? fire[2] : water[2]),
  79. noise3d((test > 0.0) ? fire[3] : water[3]));
  80. #else
  81. vec3 points[4] = (test > 0.0) ? fire : water;
  82. vec4 n = vec4(noise3d(points[0]),
  83. noise3d(points[1]),
  84. noise3d(points[2]),
  85. noise3d(points[3]));
  86. #endif
  87. vec4 color;
  88. if (test > 0.0)
  89. {
  90. /* Use noise results for fire */
  91. float p = dot(n, vec4(0.125, 0.125, 0.25, 0.5));
  92. /* Fade to black on top of screen */
  93. p -= pass_position.y * 0.8 + 0.25;
  94. p = max(p, 0.0);
  95. p = min(p, 1.0);
  96. float q = p * p * (3.0 - 2.0 * p);
  97. float r = q * q * (3.0 - 2.0 * q);
  98. color = vec4(min(q * 2.0, 1.0),
  99. max(r * 1.5 - 0.5, 0.0),
  100. max(q * 8.0 - 7.3, 0.0),
  101. 1.0);
  102. }
  103. else
  104. {
  105. /* Use noise results for water */
  106. float p = dot(abs(2.0 * n - 1.0),
  107. vec4(0.5, 0.25, 0.125, 0.125));
  108. float q = sqrt(p);
  109. color = vec4(1.0 - q,
  110. 1.0 - 0.5 * q,
  111. 1.0,
  112. 1.0);
  113. }
  114. gl_FragColor = color;
  115. }