Smooth Particle Hydrodynamics with webgpu

Ink Zhang

The Theory

Fluid Simulation

Different Types of SPH

  • WCSPH (weakly compressed sph) ✅
  • PCISPH (predictive-corrective incompressible sph)
  • IISPH (implicit incompressible sph)
  • DFSPH (divergence-free sph)

Incompressible Navier-Stokes equation

\[ \begin{align} \rho \frac{Dv}{Dt} &= \rho g - \nabla p + \mu \nabla^2 v \\ \nabla \cdot v &= 0 \end{align} \]

Which basically means this:

\[ ma = f_{ext} + f_{pres} + f_{visc} \]

Turns into this:

\[ a = \frac{f_{ext} + f_{pres} + f_{visc}}{V_j \times \rho_j} \]

  • How to get the density?

Kernel Functions

  • imagine a probe…

screenshots taken from: taichi 10_fluid_lagrangian

Compute the acceleration for particle

  • for \(i\) in particles:
    1. Evaluate density
    • \(\rho_i = \sum_j \frac{m_j}{\rho_j} \rho_j W(r_i - r_j, h) = \sum_j m_j W_{ij}\)
    1. Evaluate non-pressure force: gravity, viscosity
    • \(g\)
    • \(v\nabla^2 v_i = v\sum_jm_j\frac{v_j-v_i}{\rho_j}\nabla^2 W_{ij}\)
    1. Evaluate pressure gradient
    • \(-\frac{1}{\rho_i}\nabla p_i = -\sum_j m_j(\frac{p_j}{\rho^2_j} + \frac{p_i}{\rho^2_i})\nabla W_{ij}\)

boundary problems

  • free surface
    • density –> 0
    • clamp the minimum density
  • solid boundary
    • density –> 0
    • particles gather at the boundary
    • Create imagine particles outside boundaries

Rendering

Depth Texture

Smooth surface by filtering depth texture

Render depth texture and copy it to textures for read & write

Filter

Use Bilateral filter since it won’t smooth depth.

Pipeline

  src
  │   lib.rs
  │   particle_system.rs
  │   renderer.rs
  |   ...
  │
  ├───particle_system
  │       gpu_pass.rs
  │       grid.rs
  │       particles.rs
  │       utils.rs
  │
  └───renderer
          bind_group_layout_cache.rs
          compute_pass_copy_depth.rs
          compute_pass_depth_filter.rs
          compute_pass_depth_filter_basic.rs
          compute_pass_particle.rs
          render_pass_depth.rs
          render_pass_water.rs

Each pass struct contains lots of objects… (buffer, bind_group_layout, bind_group, pipeline_layout, pipeline, encoder, pass)

Sharing objects requires passing references everywhere… sometimes through the whole call stack…

Other stuff…

Bitonic Sort Performance Test

Implement parallel bitonic sort algorithms with Rust and Wgpu.

  • size = \(2^{8}\)
    • CPU faster than GPU
[2024-04-12T09:56:02Z INFO  bitonic_sort] Bitonic sort successful!
[2024-04-12T09:56:02Z INFO  bitonic_sort] Initialization takes: 0.4548751s
[2024-04-12T09:56:02Z INFO  bitonic_sort] Wgpu computation takes: 0.0055504s
[2024-04-12T09:56:02Z INFO  bitonic_sort] Data transfer takes: 0.0001467s
[2024-04-12T09:56:02Z INFO  bitonic_sort] CPU sorting takes: 0.000011s
  • size = \(2^{18}\)
    • Similar performance
[2024-04-12T09:57:18Z INFO  bitonic_sort] Bitonic sort successful!
[2024-04-12T09:57:18Z INFO  bitonic_sort] Initialization takes: 0.4637676s
[2024-04-12T09:57:18Z INFO  bitonic_sort] Wgpu computation takes: 0.0214897s
[2024-04-12T09:57:18Z INFO  bitonic_sort] Data transfer takes: 0.0005794s
[2024-04-12T09:57:18Z INFO  bitonic_sort] CPU sorting takes: 0.0217035s
  • size = \(2^{17}\) (release mode)
    • Similar performance
[2024-04-12T21:33:44Z INFO  bitonic_sort] Bitonic sort successful!
[2024-04-12T21:33:44Z INFO  bitonic_sort] Initialization takes: 0.3913661s
[2024-04-12T21:33:44Z INFO  bitonic_sort] Wgpu computation takes: 0.0090767s
[2024-04-12T21:33:44Z INFO  bitonic_sort] Data transfer takes: 0.000544s
[2024-04-12T21:33:44Z INFO  bitonic_sort] CPU sorting takes: 0.0098242s
  • size = \(2^{25}\)
    • GPU faster than CPU
[2024-04-12T09:53:07Z INFO  bitonic_sort] Bitonic sort successful!
[2024-04-12T09:53:07Z INFO  bitonic_sort] Initialization takes: 0.9346608s
[2024-04-12T09:53:07Z INFO  bitonic_sort] Wgpu computation takes: 0.1369619s
[2024-04-12T09:53:07Z INFO  bitonic_sort] Data transfer takes: 0.9909169s
[2024-04-12T09:53:07Z INFO  bitonic_sort] CPU sorting takes: 4.1491945s

Credit

Special thanks to:

  • Professor Tim McGraw, for teaching the lesson on Compute Shader and providing a helpful demo for reference.
  • TaichiCourse01 for their lessons of Fluid Simulation. ppt
  • taichi_sph for providing guidance in the development process.
  • Nae Zhu for his introduction of a Screen Space Fluid Rendering method.

Thank You!