Particle Upsampling Sample


Category:  Performance   Visuals
Min PC GPU: Fermi-based (GTX 4xx)
Min Tegra Device: Tegra 4

Description

The Particle Upsampling sample uses a combination of rendering techniques to simulate a cloud of particles casting shadows on a model and a floor object. The particles are rendered into a lower-resolution offscreen surface, and then up-sampled to the screen to lower the cost of the high depth complexity.

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

The Particle Upsampling sample uses a combination of rendering techniques to simulate a cloud of particles casting shadows on a model and a floor object. The particles are rendered into a lower-resolution offscreen surface, and then up-sampled to the screen to lower the cost of the high depth complexity.

The sample makes use of the following techniques:

This sample uses the following extensions, to enable functionalities that may not be available in base OpenGL or GLES:

Rendering Process

The high-level rendering loop is in SceneRendering.cpp, in SceneRenderer::renderFrame().

  1. The particles are depth-sorted along the half-angle vector (midway between the light direction and the view direction). This is done using a CPU radix sort. In this SDK sample, the particle's vertices are assumed to be static and are placed in a static Vertex Buffer Object. The depth-sorted particle indices are placed in a dynamic Element Buffer Object and updated every frame, using a double-buffering scheme to avoid blocking the rendering thread when updating the buffer.

  2. A reduced-resolution depth buffer is generated, storing the depths of the opaque geometry in the scene for the particles to be depth-tested against later on.

    Note: If "Z Pre-Pass" is enabled, the opaque geometry is first drawn to a full-resolution depth buffer (depth pre-pass) and then downsampled to reduced resolution. Otherwise, if "Z Pre-Pass" is disabled, the opaque geometry is directly drawn to the reduced-resolution depth buffer.

  3. The sorted particles are rendered in batches either front-to-back or back-to-front depending on the relative orientations of the view vector and the light vector. For each batch, the particles of this batch are first blended to the light buffer and then blended to the reduced-resolution output buffer, fetching the light buffer. The precision of these 2 buffers can be toggled between 8-bit and 16-bit per channel using the "Use FP16" button in the GUI.

  4. The opaque geometry is drawn in full-resolution to the full-resolution scene color buffer, fetching the light buffer to receive shadows from the particles. If "Z Pre-Pass" is enabled, then the full-resolution depth buffer from step 2 is used to speed up this pass.

  5. Finally, the scene color buffer is upsampled to the display resolution with a simple bilinear texture fetch.

Acknowledgments

This SDK sample is essentially a port of Simon Green's OpenCL "smokeParticles" demo with a static particle system.

See Also


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