Shallow Water

Started by
1 comment, last by dr4cula 9 years, 2 months ago

Hi,

I've been experimenting with the shallow water equations but I can't seem to get my implementation correct. I'm following this except I'm doing everything on the GPU. I'm not sure where I keep going wrong: see here. From my experimentations with the full Navier-Stokes equations, this makes sense: I remember getting visually similar results (in 2D) where the circle forms into a square-like corner (plotted a circle with velocity (1,1) at every pixel). But this only happened when I stopped the simulation after the advection step ("skipped" projection). Not sure what is happening here. I've tried changing the signs when sampling data as well as switching the order of operations around but nothing seems to work. At one point I ended up with this, which is obviously not correct.

Here are my simulation kernels (I won't post my advection kernel as it is the same one I used for my full NS solver; also note that using a staggered grid whereby a single pixel represents left-bottom pair of velocities for velocity kernels (boundaries are set appropriately to account for the array size differences)):

UpdateHeight kernel


float4 PSMain(PSInput input) : SV_TARGET {
float2 texCoord = input.position.xy * recTexDimensions.xy;
 
float vL = velocity.Sample(pointSampler, texCoord).x;
float vR = velocity.Sample(pointSampler, texCoord + float2(recTexDimensions.x, 0.0f)).x;
float vT = velocity.Sample(pointSampler, texCoord + float2(0.0f, recTexDimensions.y)).y;
float vB = velocity.Sample(pointSampler, texCoord).y;
 
float h = height.Sample(pointSampler, texCoord).x;
 
float newH = h - h * ((vR - vL) * recTexDimensions.x + (vT - vB) * recTexDimensions.y) * dt;
 
return float4(newH, 0.0f, 0.0f, 0.0f);
}
UpdateU:

float4 PSMain(PSInput input) : SV_TARGET {
float2 texCoord = input.position.xy * recTexDimensions.xy;
 
float u = velocity.Sample(pointSampler, texCoord).x;
 
float hL = height.Sample(pointSampler, texCoord - float2(recTexDimensions.x, 0.0f)).x;
float hR = height.Sample(pointSampler, texCoord).x;
 
float uNew = u + g * (hL - hR) * recTexDimensions.x * dt;
 
return float4(uNew, 0.0f, 0.0f, 0.0f);
}
UpdateV:

float4 PSMain(PSInput input) : SV_TARGET {
float2 texCoord = input.position.xy * recTexDimensions.xy;
 
float v = velocity.Sample(pointSampler, texCoord).y;
 
float hB = height.Sample(pointSampler, texCoord - float2(0.0f, recTexDimensions.y)).x;
float hT = height.Sample(pointSampler, texCoord).x;
 
float vNew = v + g * (hB - hT) * recTexDimensions.y * dt;
 
return float4(0.0f, vNew, 0.0f, 0.0f);
}

I've literally spent the entire day debugging this and I've got no idea why nothing seems to work... Hopefully some of you guys have implemented this before and can help me out.

Thanks in advance!

Advertisement

Shouldn't either U or V be sampled from y component of height? You are sampling both of them from x component:

float hL = height.Sample(pointSampler, texCoord - float2(recTexDimensions.x, 0.0f)).x;

float hR = height.Sample(pointSampler, texCoord).x;

float hB = height.Sample(pointSampler, texCoord - float2(0.0f, recTexDimensions.y)).x; // change to .y?

float hT = height.Sample(pointSampler, texCoord).x; // change to .y?

Shouldn't either U or V be sampled from y component of height? You are sampling both of them from x component:

float hL = height.Sample(pointSampler, texCoord - float2(recTexDimensions.x, 0.0f)).x;

float hR = height.Sample(pointSampler, texCoord).x;

float hB = height.Sample(pointSampler, texCoord - float2(0.0f, recTexDimensions.y)).x; // change to .y?

float hT = height.Sample(pointSampler, texCoord).x; // change to .y?

Height is stored only in the first component of a 4-component render target, i.e. currently the 3 other components of the rendertarget/texture go unused.

I've not been able to make any progress on this on my own...

This topic is closed to new replies.

Advertisement