2d Fluid shader

Hi,

I try to code a 2d fluid shader using this article as a base :
https://developer.nvidia.com/content/gpu-gems-chapter-38-fast-fluid-dynamics-simulation-gpu

But the result is far from expected.

First, all F2texRECT, H4texRECT, H1texRECT and other similar functions are missing in unity’s library texRECT wich I replaced by tex2D. But does it gives the same result ?

Secondly the logarythm sequence is not clear. I did this :

advect(coords, xNew, timestep, rdx, _VelocityMap, _MainTex);		
	jacobi(coords, xNew, alpha, rBeta, _VelocityMap, _VelocityMap);
	divergence(coords, xNew, halfrdx, _VelocityMap);
	gradient(coords, xNew, halfrdx, _VelocityMap, _VelocityMap);

I didn’t find how to get what they call Gridscale.

I try to achieve the attached image.

My code :

		float4 f4texRECTbilerp(sampler2D tex, float2 s) {
			float4 st;
			st.xy = floor(s - 0.5) + 0.5;
			st.zw = st.xy + 1;

			float2 t = s - st.xy; //interpolating factors 

			float4 tex11 = tex2D(tex, st.xy);
			float4 tex21 = tex2D(tex, st.zy);
			float4 tex12 = tex2D(tex, st.xw);
			float4 tex22 = tex2D(tex, st.zw);

			// bilinear interpolation
			return lerp(lerp(tex11, tex21, t.x), lerp(tex12, tex22, t.x), t.y);
		}
		
		void advect(float2 coords : WPOS, out float4 xNew : COLOR, uniform float timestep, uniform float rdx, uniform sampler2D u, uniform sampler2D x) {
			// Follow The Velocity Field "Back In Time"
			float2 pos = coords - timestep * rdx * tex2D(u, coords);

			// Interpolate And Write To The Output Fragment
			xNew = f4texRECTbilerp(x, pos);
		}
		
		void jacobi(half2 coords   : WPOS, out float4 xNew : COLOR, uniform half alpha, uniform half rBeta, uniform sampler2D  x, uniform sampler2D  b) {
			// Left, Right, Bottom, And Top X Samples

			half4 xL = tex2D(x, coords - half2(1, 0));
			half4 xR = tex2D(x, coords + half2(1, 0));
			half4 xB = tex2D(x, coords - half2(0, 1));
			half4 xT = tex2D(x, coords + half2(0, 1));

			// B Sample, From Center

			half4 bC = tex2D(b, coords);

			// Evaluate Jacobi Iteration
			xNew = (xL + xR + xB + xT + alpha * bC) * rBeta;
		}
		
		void divergence(half2 coords  : WPOS, out float4 div : COLOR, uniform half halfrdx, uniform sampler2D w) {
			half4 wL = tex2D(w, coords - half2(1, 0));
			half4 wR = tex2D(w, coords + half2(1, 0));
			half4 wB = tex2D(w, coords - half2(0, 1));
			half4 wT = tex2D(w, coords + half2(0, 1));

			div = halfrdx * ((wR.x - wL.x) + (wT.y - wB.y));
		}
		
		void gradient(half2 coords   : WPOS, out float4 uNew : COLOR, uniform half halfrdx, uniform sampler2D p, uniform sampler2D w) {
			half pL = tex2D(p, coords - half2(1, 0));
			half pR = tex2D(p, coords + half2(1, 0));
			half pB = tex2D(p, coords - half2(0, 1));
			half pT = tex2D(p, coords + half2(0, 1));

			uNew = tex2D(w, coords);
			uNew.xy -= halfrdx * half2(pR - pL, pT - pB);
		}		

		void boundary(half2 coords : WPOS, half2 offset : TEX1, out float4 bv : COLOR, uniform half scale, uniform sampler2D x) {
			bv = scale * tex2D(x, coords + offset);
		}
		
		void surf (Input IN, inout EditorSurfaceOutput o) 
		{
			o.Normal = float3(0.0,0.0,1.0);
			o.Alpha = 1.0;
			o.Albedo = 0.0;
			o.Emission = 0.0;
			o.Gloss = 0.0;
			o.Specular = 0.0;
			o.Custom = 0.0;
	

		// Apply The First 3 Operators In Equation 12.
		//u = advect(u);
		//u = diffuse(u);
		//u = addForces(u);
		// Now Apply The Projection Operator To The Result.
		//p = computePressure(u);
		//u = subtractPressureGradient(u, p);
		//uTemp = advect(u);
		//swap(u, uTemp);
	
			float gridScale = 1;
			float2 coords = (IN.uv_VelocityMap.xyxy).xy;
			float4 xNew;
			float timestep = _Time * _HSpeed.xxxx;
			float rdx = 1.0 / gridScale;

			advect(coords, xNew, timestep, rdx, _VelocityMap, _MainTex);		

			half alpha = 1;
			half rBeta = 1;
			half4 div;
			jacobi(coords, xNew, alpha, rBeta, _VelocityMap, _VelocityMap);
			
			half halfrdx = rdx * 0.5;
			divergence(coords, xNew, halfrdx, _VelocityMap);
			
			half4 uNew;
			gradient(coords, xNew, halfrdx, _VelocityMap, _VelocityMap);

			o.Albedo =  xNew;
			

			o.Normal = normalize(o.Normal);
		}

1281984--57902--$jupiter_title.jpg

In a simpler way, I think you could do this using flow map only : Graphics Runner: Animating Water Using Flow Maps

It is for water but you can use this on anything. Im using flow map for smoke for example and this give me a nice movement.

Concerning your texRECT : http://forum.unity3d.com/threads/13933-texRECT-and-tex2D

http://scrawkblog.com/2013/05/21/gpu-gems-to-unity-2d-fluid-simulation/