]> git.tdb.fi Git - libs/gl.git/blobdiff - demos/forestpond/data/fluidsim_velocity.glsl
Implement water simulation and surface shader for forest pond
[libs/gl.git] / demos / forestpond / data / fluidsim_velocity.glsl
diff --git a/demos/forestpond/data/fluidsim_velocity.glsl b/demos/forestpond/data/fluidsim_velocity.glsl
new file mode 100644 (file)
index 0000000..b564b23
--- /dev/null
@@ -0,0 +1,46 @@
+import fluidsim;
+
+#pragma MSP stage(compute)
+void main()
+{
+       ivec2 size = imageSize(velocity_out);
+       ivec2 coord = ivec2(gl_GlobalInvocationID.xy)+ivec2(1, 1);
+       if(coord.x>=size.x-1 || coord.y>=size.y-1)
+               return;
+
+       float surface = texelFetch(surface_in, coord, 0).x;
+       float depth = surface-texelFetch(bottom_in, coord, 0).x;
+       float surface_left = texelFetch(surface_in, coord-ivec2(1, 0), 0).x;
+       float surface_right = texelFetch(surface_in, coord+ivec2(1, 0), 0).x;
+       float depth_right = surface_right-texelFetch(bottom_in, coord+ivec2(1, 0), 0).x;
+       float surface_down = texelFetch(surface_in, coord-ivec2(0, 1), 0).x;
+       float surface_up = texelFetch(surface_in, coord+ivec2(0, 1), 0).x;
+       float depth_up = surface_up-texelFetch(bottom_in, coord+ivec2(0, 1), 0).x;
+       vec2 velocity = texelFetch(velocity_in, coord, 0).xy;
+
+       // Advection step: move velocity vectors 
+       vec2 uv_coord = (vec2(coord)+vec2(0.5))/size;
+       vec2 offset = vec2(0.5, -0.5)/size;
+       vec2 multi = delta_time/size;
+       vec2 v_right = vec2(velocity.x, textureLod(velocity_in, uv_coord+offset, 0).y);
+       vec2 v_up = vec2(textureLod(velocity_in, uv_coord-offset, 0).x, velocity.y);
+       vec2 new_velocity = vec2(textureLod(velocity_in, uv_coord-v_right*multi, 0).x,
+               textureLod(velocity_in, uv_coord-v_up*multi, 0).y)*velocity_damping;
+
+       // Update step: change velocities based on surface level differences
+       vec2 source_depth = mix(vec2(depth_right, depth_up), vec2(depth), greaterThan(vec2(surface), vec2(surface_right, surface_up)));
+       new_velocity += (vec2(surface)-vec2(surface_right, surface_up))*0.1*gravity*delta_time*min(source_depth/residual_depth, 1.0);
+
+       if(time>=drop_time && time<=drop_time+0.01 && depth>1.0)
+       {
+               ivec2 d = coord-drop_pos;
+               if(d.x*d.x+d.y*d.y<4)
+               {
+                       float v = cos(fract(time-drop_time)*628.3)*100.0;
+                       new_velocity.x += normalize(vec2(d.x+0.5, d.y)).x*v;
+                       new_velocity.y += normalize(vec2(d.x, d.y+0.5)).y*v;
+               }
+       }
+
+       imageStore(velocity_out, coord, vec4(new_velocity, 0.0, 0.0));
+}