Compute Particles Sample


Category: Compute
Min PC GPU: Fermi-based (GTX 4xx)
Min Tegra Device: Tegra K1

Description

The Compute Particles sample shows how OpenGL Compute Shaders can be used along with OpenGL rendering to create complex animations and effects entirely on the GPU.

APIs Used

Shared User Interface

The OpenGL samples all share a common app framework and certain user interface elements, centered around the "Tweakbar" panel on the left side of the screen which lets you interactively control certain variables in each sample.

To show and hide the Tweakbar, simply click or touch the triangular button positioned in the top-left of the view.

Other controls are listed below.

Device Input Result
touch 1-Finger Drag Orbit-rotate the camera
2-Finger Drag Move up/down/left/right
2-Finger Pinch Scale the view
mouse Left-Button Drag Orbit-rotate the camera
Right-Button Drag Move up/down/left/right
Middle-Click Drag Scale the view (up:out, down:in)
keyboard Escape Quit the application
  Tab Toggle Tweakbar visibility
gamepad Start Toggle Tweakbar visibility
  Right Thumbstick Orbit-rotate the camera
  Left Thumbstick Move forward/backward. Slide left/right
  Left/Right Triggers Move up/down

Technical Details

Introduction

This sample shows how compute shaders can be used to implement massively parallel animation tasks on the GPU, and pass the results to rendering. It demonstrates how vertex shaders can access any element of the compute shader's output buffer by indexing.

The high-level stages are as follows:

  1. The compute shader updates the positions and velocities of the particles on the GPU.

  2. The vertex shader accesses the resulting particle positions and expands them out to 4-vertex quads.

  3. The fragment shader applies a computed exponential fall-off alpha to draw smooth particles.

UI Options

The following options can be adjusted in the tweak UI:

Details

The details of each stage are as follows:

Compute Shader

The compute shader operates on a pair of in/out buffers: one for positions and one for velocities. The velocities are used only by the compute shader, while the positions are read and written by the compute shader, and read by the rendering shader. The steps in the per-frame compute shader update are:

  1. The sources used to update each particle are read: these include previous position, previous velocity, and the position and strength of the attractor.

  2. Next, a vector-valued multi-octave (4 octaves) smooth noise value is computed and added to the velocity vector. This addition is scaled by the adjustable noise magnitude parameter.

  3. An attraction vector is computed, including a quadratic falloff (this looks in the code to be a scaling by the inverse cube, but the vector is not normalized, so one factor is for the normalization). This vector is scaled by the adjustable attractor magnitude and added to the velocity.

  4. The velocity is added to the particle position as an integration step.

  5. The velocity is scaled by a damping factor to keep the system's energy in check.

Vertex Shader

The vertex shader serves multiple purposes in this rendering pipeline. Not only does it project the vertices, it also serves as a simple "vertex amplifier," splitting the N particle positions in 4N vertices, offsetting to the four corners of each particle.

  1. First, the particle index is computed by dividing the vertex ID by 4. Every four-vertex quad represents a single particle.

  2. The position of the particle is looked up in the compute shader buffer.

  3. The 0.0-1.0 U and V position of the vertex in the quad is computed via bitmasking of the vertex ID (i.e. its value mod 4). This is stored as quadPos, which is used directly as the texture coordinates.

  4. The quadPos is used to offset the particle center horizontally and vertically to form the correct quad corner.

  5. The resulting vertex is transformed and output.

Fragment Shader

The fragment shader is extremely simple. It writes the passed-in varying color as the RGB channels and computes an exponential fall-off from the center of the particle, placing it in the alpha channel. It discards the fragment if the computed alpha is close to zero.

See Also


NVIDIA® GameWorks™ Documentation Rev. 1.0.200601 ©2014-2020. NVIDIA Corporation. All Rights Reserved.