JLUK Logo - Jonas Lukasczyk
Dr. Jonas Lukasczyk - Staff Scientist at TU Kaiserslautern

Particle Advection with WebGL

Rendering Steps

Compute Shader   ➤   Depth Buffer   ➤   SSAO Shader   ➤   Blur Shader

This demo exploits the GPU the old fashioned way: Particles are represented as a Floating Point Texture where each pixel stores the xyz-position and lifetime of a particle in the rgb and alpha channels, respectively.

To iterate the positions the renderer uses a Render Target of the same size as the texture and renders a fullscreen quad where now the fragment shader computes the new positions and lifetimes for all particles by adding to the current position a small advection vector. If this advection vector would be chosen totally arbitrarily each frame the particles would randomly jump around instead of this smooth flow like movement. Therefore, the advection vector is calculated with three dimensional Perlin Noise. This noise function has the nice property that it is locally continuous so a vector chosen close to the old particle position will yield a smooth transition in the advection vector.

The renderer then writes out the Depth Buffer of the scene containing the particle system which is subsequently passed to a custom Screen Space Ambient Occlusion (SSAO) shader. Finally, in the post-processing the image is blurred with a Gaussian Filter to make the particles appear more volumetric and counter the artifacts resulting from SSAO. It is also possible to render an outline of the particles by applying a depth based Canny Edge Detector and make them more appealing to the eye by augmenting the final render output with Film Grain.

Source Code

Rendering Pipeline Shaders