Volumetric effects

A powerful feature of REDsdk is the rendering of volumetric effects. We call volumetric effects all the visual effects induced by the light passing through media particles like gas, smoke, dust, etc.. It is often called 'participating media' in the literature.

In REDsdk, any volumetric effect is added in the scene graph with the intermediate of a special shape named RED::IVolumeShape.

The volume shape contains all the effects of the scene as RED::VolumetricEffect objects. This RED::VolumetricEffect class is an atomic class, all the REDsdk built-in volumetric effects are of this type and custom effects must inherit it.

A volumetric effect has several properties:

Volumetric effect properties

Anisotropic phase function: the amount of light in the view direction depends on the light and view directions

The media can be:

Defining volumetric boxes

The first and easiest volumetric effect provided by REDsdk is RED::VolumetricEffectBoxVolume. It adds a media inside a volume defined by a box. The box is simply defined by its extents in the scene aligned with the world coordinates axis.

Box volume filled with participating media enlightened by an area light

task

Task: A simple volumetric effect example

The following code shows how to add a simple volumetric effect in the scene.

// Enable volumetric rendering:
RED::IOptions* icamopt = icamera->As< RED::IOptions >();
RC_TEST( icamopt->SetOptionValue( RED::OPTIONS_RAY_VOLUME, 1, iresmgr->GetState() ) );

// Create a volume shape to hold volumetric effect:
RED::Object* volume = RED::Factory::CreateInstance( CID_REDVolumeShape );
RED::IVolumeShape* ivolume = volume->As< RED::IVolumeShape >();

// Set volume rendering parameters:
RC_TEST( ivolume->SetRayMarchingStep( 1, iresmgr->GetState() ) );
RC_TEST( ivolume->SetRayCutoff( 0.001, iresmgr->GetState() ) );
RC_TEST( ivolume->SetScatteringSamples( 128, iresmgr->GetState() ) );

// Add the shape to the scenegraph:
RC_TEST( icamera->AddShape( volume, iresmgr->GetState() ) );

// Create the volumetric effect:
RED::VolumetricEffectBoxVolume effect;

// Set the volumetric effect parameters:
effect.SetSigmaA( RED::Vector3( 0.001 ) );
effect.SetSigmaS( RED::Vector3( 0.02 ) );
effect.SetBox( RED::Vector3( -100.0 ), RED::Vector3( 100.0 ) );

// Add the volumetric effect to the volume shape:
RC_TEST( ivolume->AddVolumetricEffect( &effect, iresmgr->GetState() ) );

The process is divided into four main steps:

  1. Enable the volume rendering in the camera options.
  2. Create a volume shape and add it to the scene graph.
  3. Create the volumetric effect and add it to the volume shape.
  4. Set the volumetric effect parameters.

Light shafts

The second volumetric effect provided by the API is RED::VolumetricEffectLightVolume. This effect adds media inside all the volumes of the scene lights to create 'light shaft' effects.

Real life light shaft

The light types that define a volume are:

Note:

All the other lights (directionnal, area, sun, sky) are ignored by this kind of effect and do not add any media in the scene. But they still enlighten the medium created by other lights or effects.

The volume creation by a valid light can be disabled using the RED::RM_DEFINE_VOLUME render mode set by the RED::ILightShape::SetRenderMode function.

Writing custom volumetric effects

As said previously, the RED::VolumetricEffect class is atomic and is the base class of all the specialized volumetric effects. Writing custom effect is as simple as creating a new sub-class filling this interface.

By this mechanism, REDsdk lets the user the ability to define its own media properties:

Volume boundaries of effects are set thanks to the RED::VolumetricEffect::GetVolumeIntervals. By implementing the interface, the user must write this method which, given a ray, returns its intersections with the custom volume.

The user has also the ability to define heterogeneous medium by writing the RED::VolumetricEffect::GetDensity function and returning different density values according to the position (using a noise function for example).

A custom heterogeneous media in a spot light volume

Rendering options

To enable the volumetric rendering in REDsdk, one must set the right option using the RED::IOption interface of the viewpoint: RED::OPTIONS_RAY_VOLUME. This option activates or deactivates the calculation of software ray-traced volumetric effects. It also gives the ability to define the level of reflections and refractions after which the calculation is stopped.

To activate the volumetric calculations in the Global Illumination process, the user must activate the RED::OPTIONS_RAY_GI_ENABLE_VOLUME option.

As we have seen previously, the participating media can be enlightened by surrounding lights in the scene. This is what we called in-scattering. Each light can be individually activated or deactivated for this step using the RED::RM_ENLIGHTEN_VOLUME render mode. To change it, simply call the RED::ILightShape::SetRenderMode function. Sometimes, it can be useful to deactivate it for the lights that are far from the scene medium or for the ambient lights like sky or sun. By default, this option is activated: all the lights are used to enlighten the medium.