Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

268 рядки
6.9 KiB

  1. [vert.glsl]
  2. #version 120
  3. uniform float u_Time;
  4. attribute vec2 in_Position;
  5. varying vec4 pass_Position;
  6. varying vec3 water[4];
  7. varying 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 120
  36. uniform float u_Time;
  37. varying vec4 pass_Position;
  38. varying vec3 water[4];
  39. varying vec3 fire[4];
  40. vec4 mod289(vec4 x)
  41. {
  42. return x - floor(x * (1.0 / 289.0)) * 289.0;
  43. }
  44. vec4 perm(vec4 x)
  45. {
  46. return mod289(((x * 34.0) + 1.0) * x);
  47. }
  48. float noise3d(vec3 p)
  49. {
  50. vec3 a = floor(p);
  51. vec3 d = p - a;
  52. d = d * d * (3.0 - 2.0 * d);
  53. vec4 b = a.xxyy + vec4(0.0, 1.0, 0.0, 1.0);
  54. vec4 k1 = perm(b.xyxy);
  55. vec4 k2 = perm(k1.xyxy + b.zzww);
  56. vec4 c = k2 + a.zzzz;
  57. vec4 k3 = perm(c);
  58. vec4 k4 = perm(c + 1.0);
  59. vec4 o1 = fract(k3 * (1.0 / 41.0));
  60. vec4 o2 = fract(k4 * (1.0 / 41.0));
  61. vec4 o3 = o2 * d.z + o1 * (1.0 - d.z);
  62. vec2 o4 = o3.yw * d.x + o3.xz * (1.0 - d.x);
  63. return o4.y * d.y + o4.x * (1.0 - d.y);
  64. }
  65. void main(void)
  66. {
  67. /* Dither the transition between water and fire */
  68. float test = pass_Position.z * pass_Position.w + 1.5 * sin(u_Time);
  69. vec2 d = vec2(16.0, 9.0) * pass_Position.xy;
  70. test += 0.5 * (length(fract(d) - 0.5) - length(fract(d + 0.5) - 0.5));
  71. /* Compute 4 octaves of noise */
  72. vec3 points[4] = (test > 0.0) ? fire : water;
  73. vec4 n = vec4(noise3d(points[0]),
  74. noise3d(points[1]),
  75. noise3d(points[2]),
  76. noise3d(points[3]));
  77. vec4 color;
  78. if (test > 0.0)
  79. {
  80. /* Use noise results for fire */
  81. float p = dot(n, vec4(0.125, 0.125, 0.25, 0.5));
  82. /* Fade to black on top of screen */
  83. p -= pass_Position.y * 0.8 + 0.25;
  84. p = max(p, 0.0);
  85. p = min(p, 1.0);
  86. float q = p * p * (3.0 - 2.0 * p);
  87. float r = q * q * (3.0 - 2.0 * q);
  88. color = vec4(min(q * 2.0, 1.0),
  89. max(r * 1.5 - 0.5, 0.0),
  90. max(q * 8.0 - 7.3, 0.0),
  91. 1.0);
  92. }
  93. else
  94. {
  95. /* Use noise results for water */
  96. float p = dot(abs(2.0 * n - 1.0),
  97. vec4(0.5, 0.25, 0.125, 0.125));
  98. float q = sqrt(p);
  99. color = vec4(1.0 - q,
  100. 1.0 - 0.5 * q,
  101. 1.0,
  102. 1.0);
  103. }
  104. gl_FragColor = color;
  105. }
  106. [vert.hlsl]
  107. float mod289(float x)
  108. {
  109. return x - floor(x * (1.0 / 289.0)) * 289.0;
  110. }
  111. void main(float2 in_Position : POSITION,
  112. uniform float u_Time,
  113. out float4 out_Position : POSITION,
  114. out float4 pass_Position : TEXCOORD0,
  115. out float3 water[4] : TEXCOORD1,
  116. out float3 fire[4] : TEXCOORD5)
  117. {
  118. float3x3 r = float3x3(0.36, 0.48, -0.8, -0.8, 0.60, 0.0, 0.48, 0.64, 0.60);
  119. float3 p_pos = mul(r, float3(in_Position * float2(16.0, 9.0), 0.0));
  120. float3 p_time = mul(r, float3(0.0, 0.0, u_Time * 2.0));
  121. /* Noise sampling points for water */
  122. water[0] = p_pos / 2.0 + p_time;
  123. water[1] = p_pos / 4.0 + p_time;
  124. water[2] = p_pos / 8.0 + p_time;
  125. water[3] = p_pos / 16.0 + p_time;
  126. /* Noise sampling points for fire */
  127. p_pos = 16.0 * p_pos - mul(r, float3(0.0, mod289(u_Time) * 128.0, 0.0));
  128. fire[0] = p_pos / 2.0 + p_time * 2.0;
  129. fire[1] = p_pos / 4.0 + p_time * 1.5;
  130. fire[2] = p_pos / 8.0 + p_time;
  131. fire[3] = p_pos / 16.0 + p_time;
  132. /* Pass rotated screen coordinates */
  133. pass_Position.xy = in_Position;
  134. float2x2 rot = float2x2(cos(u_Time), sin(u_Time), -sin(u_Time), cos(u_Time));
  135. pass_Position.zw = mul(rot, in_Position);
  136. out_Position = float4(in_Position, 0.0, 1.0);
  137. }
  138. [frag.hlsl]
  139. float4 mod289(float4 x)
  140. {
  141. return x - floor(x * (1.0 / 289.0)) * 289.0;
  142. }
  143. float4 perm(float4 x)
  144. {
  145. return mod289(((x * 34.0) + 1.0) * x);
  146. }
  147. float noise3d(float3 p)
  148. {
  149. float3 a = floor(p);
  150. float3 d = p - a;
  151. d = d * d * (3.0 - 2.0 * d);
  152. float4 b = a.xxyy + float4(0.0, 1.0, 0.0, 1.0);
  153. float4 k1 = perm(b.xyxy);
  154. float4 k2 = perm(k1.xyxy + b.zzww);
  155. float4 c = k2 + a.zzzz;
  156. float4 k3 = perm(c);
  157. float4 k4 = perm(c + 1.0);
  158. float4 o1 = frac(k3 * (1.0 / 41.0));
  159. float4 o2 = frac(k4 * (1.0 / 41.0));
  160. float4 o3 = o2 * d.z + o1 * (1.0 - d.z);
  161. float2 o4 = o3.yw * d.x + o3.xz * (1.0 - d.x);
  162. return o4.y * d.y + o4.x * (1.0 - d.y);
  163. }
  164. void main(in float4 pass_Position : TEXCOORD0,
  165. in float3 water[4] : TEXCOORD1,
  166. in float3 fire[4] : TEXCOORD5,
  167. uniform float u_Time,
  168. out float4 out_FragColor : COLOR)
  169. {
  170. /* Dither the transition between water and fire */
  171. float test = pass_Position.z * pass_Position.w + 1.5 * sin(u_Time);
  172. float2 d = float2(16.0, 9.0) * pass_Position.xy;
  173. test += 0.5 * (length(frac(d) - 0.5) - length(frac(d + 0.5) - 0.5));
  174. float3 points[4];
  175. points[0] = (test > 0.0) ? fire[0] : water[0];
  176. points[1] = (test > 0.0) ? fire[1] : water[1];
  177. points[2] = (test > 0.0) ? fire[2] : water[2];
  178. points[3] = (test > 0.0) ? fire[3] : water[3];
  179. /* Compute 4 octaves of noise */
  180. float4 n = float4(noise3d(points[0]),
  181. noise3d(points[1]),
  182. noise3d(points[2]),
  183. noise3d(points[3]));
  184. float4 color;
  185. if (test > 0.0)
  186. {
  187. /* Use noise results for fire */
  188. float p = dot(n, float4(0.125, 0.125, 0.25, 0.5));
  189. /* Fade to black on top of screen */
  190. p -= pass_Position.y * 0.8 + 0.25;
  191. p = max(p, 0.0);
  192. p = min(p, 1.0);
  193. float q = p * p * (3.0 - 2.0 * p);
  194. float r = q * q * (3.0 - 2.0 * q);
  195. color = float4(min(q * 2.0, 1.0),
  196. max(r * 1.5 - 0.5, 0.0),
  197. max(q * 8.0 - 7.3, 0.0),
  198. 1.0);
  199. }
  200. else
  201. {
  202. /* Use noise results for water */
  203. float p = dot(abs(2.0 * n - 1.0),
  204. float4(0.5, 0.25, 0.125, 0.125));
  205. float q = sqrt(p);
  206. color = float4(1.0 - q,
  207. 1.0 - 0.5 * q,
  208. 1.0,
  209. 1.0);
  210. }
  211. out_FragColor = color;
  212. }