This is my implementation of a 2D Fluid Simulator in Godot 3.4.2, running on the GPU through Godot’s shader language. It attempts to solve the Navier-Stokes equation in real time by taking advantage of the parallelism of GPU’s. There’s a lot of great resources I’ll link to on that subject below. It’s not as accurate as other simulations, and a major hurdle was the lack of proper multi-pass post-processing support in Godot.

The main demonstration uses layered viewports to simulate multi-passes that converge on solutions for the viscosity as well as the pressure gradient of every pixel. However, every viewport in a scene adds a delay to the final output image. This problem becomes more pronounced as the number of Jacobi iterations for solving the pressure gradient increases. Tutorials suggest setting it 50-100. I have it at 16.

Since the solution to the pressure gradient is perpetually lagging behind the rest of the math (and insufficient anyway), I also don’t use the final vector field as the next frame’s initial vector field. Doing so rapidly caused massive disturbances to the vector field and flashing lights (warning)! I opted instead for using the vector field after viscosity had been added (and before the pressure gradient was subtracted) as the next frame’s initial vector field.

I eventually implemented a single-pass solution after facing challenges to the multi-pass solution. It uses a semi-lagrangian scheme to solve for pressure, and saves the result in the vector fields z-component. Ultimately, I found the multi-pass solution still looked the best. Both demo scenes are included for your own experimentation.

Please share your feedback and suggestions. I’m especially hopeful there are still improvements to be made to the technical side of the simulation.

Github: https://github.com/Maaack/2D-Fluid-Simulation Itch.io: https://maaack.itch.io/2d-fluid-simulator-in-godot

Reference Material: https://developer.download.nvidia.com/books/HTML/gpugems/gpugems_ch38.html https://www.ixm-ibrahim.com/explanations/2d-fluid-simulation https://hal.inria.fr/inria-00596050/document https://github.com/PavelDoGreat/WebGL-Fluid-Simulation https://github.com/haxiomic/GPU-Fluid-Experiments https://github.com/mharrys/fluids-2d

Good job. 2D Navier-stokes in Godot is not an easy task. I've looked at your project. It seems that you use viewports and viewport textures to emulate the multipass shader. I went through the same reasoning (perhaps I should have used the backbuffer node too). You can check it out here. I've not took the time to make a tutorial about that. I've planned to, but dunno when.

@"Casual Garage Coder" Yeah, I was the one peppering you with questions about your implementation :) . From what I remember, you used a single-pass solution from https://hal.inria.fr/inria-00596050/document. I thought your results turned out really good, and am curious about the exact values you used. I struggled converting the HLSL in that paper into Godot's shader language, and ended up not even using it for the main demonstration.

Since you're here... I was wondering what's the advantage of having GL_RGBA32 texture as backbuffers?

Thanks in advance :tongue:

Sorry for the late response. The advantage of GL_RGBA32 is that the precision is (almost) the same for any value. The halt 16-bit as a fixed precision depending on the value range which can led to some artifacts. As I've said, there was not so much artefacts due to the fact that values (velocity, vorticity, even colors) are high enough.

16 days later

v1.1.0 This version optimizes the shaders to support additional viscosity passes (8). Some additional tuning makes it behave slightly more water-like.