Volume Rendering

Please note that the effect described in this page refers to localized volumes such as clouds, smoke and fire. For the global, uniform fog, please refer to this page instead.


Table Of Contents


Volume Rendering Explained

Redshift can render non-homogeneous volume objects such as smoke and fire. A volume's shape can be specified either through an OpenVDB file or, in certain cases, via each individual DCC's volume creation functionality.


Volume objects have to be stored on the GPU's memory in their entirety and are not handled by Redshift's out-of-core system. Therefore, if a scene uses too many different volume objects or if these volume objects are of a particularly high resolution and do not fit on the GPU's memory, rendering will be aborted with an out-of-VRAM error message.



To define the volume's shading, a Redshift Volume Shader needs to be assigned to the volume. This is explained below.


A cloud bunny in the Cornell box


OpenVDB files and channels

OpenVDB files are to volumes what EXR files are to textures. While a texture stores pixels (also called texels), an OpenVDB file stores voxels which are 3D pixels. Each voxel stores information that describes the volume at a particular XYZ point. For example, it can store a density value which tells the renderer how opaque or transparent the volume is at that point. In some ways, this is similar to the alpha channel in a PNG or EXR file.

OpenVDB organizes its voxel data in channels. As mentioned above, a typical channel is 'density'. Another channel is 'temperature' which tells us how cold or hot a voxel is. As it will be shown later, the temperature channel can be used to render fire.

One thing to remember with OpenVDB channels is that they are named. In theory, a 3d app could be exporting VDB density information in a channel named "bob". Thankfully, though, most applications follow fairly standard naming conventions. In a later section of this document we'll show how to use Redshift log files to find out the channel names within an OpenVDB file. Knowing the channel names of your OpenVDB file is essential when using the Redshift Volume Shader, as it will be shown below!


Creating a volume grid


The Volume Object Settings

Display Mode

Selects how the volume data will be shown in the 3d app's viewport. The choices are Bounding Box (where only the bounding box is shown), Points (where a number of representative points from the grid are shown) and Bounding Box & Points (where both the bounding box and points are shown). The number of points shown is controlled by the Max Points and Prune Threshold, explained below


Keep Points In Memory

Normally, when switching to a bounding box view, any allocated preview points are freed. Enabling this option keeps the preview points in memory so that the user can quickly switch between bounding box and points without having to resample the OpenVDB file.


Max Points

Specifies the maximum number of points that would be drawn if the OpenVDB file was completely filled.


Prune Threshold

Any OpenVDB voxels that are lower or equal to this value won't be drawn as points. This is useful to cut away empty space during volume data previewing.


Creating A Redshift Volume Shader

To render a Redshift Volume, you have to assign a Redshift Volume Shader to it. Adjusting the settings of the Redshift Volume Shader defines the look of the volume object.


Before You Proceed, Create A Volume-Affecting Light!

To be able to see your volume, you'll need to place one or more volume-affecting lights in your scene. Simply create a Redshift light (any kind: physical, domelight, IES, etc) and ensure that its volume contribution scale is set to a value higher than 0.0.


Important note! If the scene doesn't contain any volume-affecting lights, the volume will render black!


Using The Redshift Volume Shader

The Scatter/Absorption/Emission Shading Components

As it can be seen, the Redshift Volume Shader is divided in three shading components: scatter, absorption and emission.

You can think of scatter as "diffuse". Absorption is "transparency". And emission is "incandescence" or "self-illumination".

Therefore, if you want to make your volume brighter or darker, you need to adjust the scatter parameters. If you want to make your volume more solid or more transparent, you need to adjust the absorption parameters. And, finally, if your volume represents a self-illuminating effect like fire and want to make it brighter or dimmer, you need to adjust the emission parameters.


Channel Names


Important note! If you don't set the scatter or emission channel names, Redshift won't render the volume!


All three shading components have a "channel" textbox. As mentioned earlier, each OpenVDB voxel can contain values that describe different properties of the volume. Typical examples include 'density' and 'temperature'. If your OpenVDB file was exported from SideFX Houdini, it will almost certainly contain a channel called 'density'. And if it's a fire or explosion effect, it will also contain a channel called 'temperature'. The density channel name (in this case 'density') should be typed in the scatter channel box. And the temperature channel name (in this case 'temperature') should be typed in the emission channel box.

But what if our OpenVDB doesn't contain channels called 'density' or 'emission'? What if they were called differently? You can use the Redshift Log File to find out which channels are contained in the OpenVDB file. When Redshift loads an OpenVDB file, it prints out the names of all the channels it contains. This is how this information looks like in the Redshift log file:


Preparing volume objects...
Loading: c:\MyVDBFiles\bunny_cloud.vdb
Contained grids: 'density' Done!
Dim: (577, 572, 438).
Num loaded grids: 1. Num voxels total: 26749120
Time to process 1 volume objects: 0ms


In this particular case, we can see that bunny_cloud.vdb contains one channel called 'density', so we type 'density' (without the quotes) in the scatter's channel box.


Scattering and absorption

Scattering and absorption are similar to "diffuse" and "transparency" respectively. Redshift computes these using the OpenVDB file's density channel. We'll demonstrate how this happens through a series of examples.

The most basic adjustment of scattering and absorption can happen through the "Scatter Coefficient" and "Absorption Coefficient" parameters. Increasing the scatter coefficient makes the volume brighter. Increasing the absorption coefficient makes the volume more opaque. A thing to keep in mind is that, the more opaque the volume, the less light it will allow to travel through it. In other words, high absorption means the volume render darker. If you want to preserve the same approximate intensity, we recommend adjusting the scatter and absorption coefficients together. I.e. if you want to make your volume more opaque by doubling the absorption coefficient, also double the scatter coefficient. This is demonstrated in the following examples:


 

Scatter Coefficient=1.0. Absorption Coefficient=1.0

Scatter Coefficient=3.0. Absorption Coefficient=3.0

Scatter Coefficient=10.0. Absorption Coefficient=10.0


If you want to make the volume brighter or darker, you can adjust the scatter coefficient without increasing the absorption one, as shown below:


Scatter Coefficient=5.0. Absorption Coefficient=5.0

Scatter Coefficient=10.0. Absorption Coefficient=5.0


You can also use the "Scatter Tint" to adjust the overall color of the volume, as shown below


White Tint (Scatter Coefficient=3.0. Absorption Coefficient=3.0)

Blue tint


More advanced manipulation of scattering can happen vie the scatter color ramp. As mentioned above, scattering and absorption happen by remapping the density OpenVDB channel. The scatter color ramp allows us to map the density channel into different colors.

Let's assume that we want low density areas to be tinted green, while high density areas to be tinted red. We can use the ramp shown below (shown in Maya)


…and get the following psychedelic result!



Notice how the outer edges of the bunny (low density areas) are bright (lower absorption) while the deeper, denser parts are now darker because of the increased absorption.


Without the Absorption ramp (Scatter Coefficient=3.0. Absorption Coefficient=3.0)

With the Absorption ramp (Scatter Coefficient=1.5, Absorption Coefficient=3.0)


Emission

The emission component is useful when creating effects such as fire and explosions. For this section, we'll use the fire.vdb file which was downloaded from http://www.openvdb.org/download
This file contains both a density and a temperature channel, as it can be seen in the Redshift log file:


Preparing volume objects...
Loading: c:\MyVDBFiles\fire.vdb
Contained grids: 'density' 'temperature' Done!
Dim: (161, 366, 153).
Num loaded grids: 1. Num voxels total: 10707904
Time to process 1 volume objects: 0ms


We, therefore, type 'density' (without the quotes) in the scatter channel textbox and 'temperature' (without the quotes) in the emission channel textbox.

This is how the fire vdb file looks like without and with emission


Without emission, we can only see the smoke (density) part

With emission we can see the fire effect


Achieving the effect shown above involves adjusting the emission color ramp. The reason for that is that the temperature channel that is stored in the OpenVDB file is simply a number per voxel which tells us how hot a voxel is. It doesn't describe how red or yellow the fire is. It's up to the user to adjust the emission color ramp to 'translate' the temperature value into emissive colors.


For the above example, we used a ramp that looks like this:



One way to read the above ramp is this:

Achieving the expected look for emission can sometimes be challenging for two reasons:

 

Emission Mode

Emission mode sets the method of control for emission color with the following options:

Emission Mode: Color Ramp
(with Default Ramp)
Color Ramp
(with Flame Ramp)
Blackbody

 

Temperature

The temperature parameter maps the emission value to a Kelvin temperature range. This temperature value drives both the color and the emission intensity.

Only relevant when Emission Mode is set to Blackbody

Temperature: 0 3000 6500 (default) 9000 12000
Note as the temperature parameter is increased the color of the emission changes and the emission intensity increases as well resulting in a brighter scene.

 

Offset

Offset interpolates the emission intensity between the emission channel value and the calculated physically correct radiance.

For physically correct results offset should be left at the default value of 1. Lower values will result in a more even and constant emission.

Only relevant when Emission Mode is set to Blackbody

Offset: 1 (default) 0 0.5 2


Advanced Topics

Shadow Density Scale

In the advanced tab of the Redshift Volume Shader, you can find a parameter called "shadow density scale". This parameter allows a volume to appear more transparent or more opaque to shadow rays. It is, in essence, a "trick" that can help emulate multiple scattering, i.e. the effect of light bouncing around a volume. This can be achieved by setting the shadow density scale below 1.0.

The other way for allowing more light to pass through the volume would have been to reduce its absorption. However, this would make the volume appear more 'puffy' and transparent. The shadow density scale, on the other hand, allows the volume to retain its "tightness" while allowing more light to pass through it, as shown below.


Shadow density scale=1.0 (Scatter Coefficient=3.0. Absorption Coefficient=3.0)

Shadow density scale=0.5 (Scatter Coefficient=3.0, Absorption Coefficient=3.0)


Range Remapping

The values stored in OpenVDB channels can vary wildly depending on the 3d app that was used to author them. This can be true for both density and emission channels.
The range remapping controls found in the advanced tab of the Redshift Volume Shader, allow the adjustment of these values just before Redshift uses them. The old min/max range is remapped to the new min/max range.

For example, a temperature channel might contains values that range between 0 and 100 but the emission color ramp only accepts inputs ranging between 0 and 1. In this case, the user should use old min=0, old max=100 and leave new min and new max at their default 0 and 1 respectively. In essence, this would 'squash' the 0->100 range into a 0->1 range.


Noise

As mentioned above, a volume-affecting light is required in the scene in order to be able to see our volumes. Each light has a "volume samples" parameter which defines the quality of lighting on the volume. If a volume is rendering noisy/grainy, it's likely that it's being lit by a light that doesn't have enough samples. The following pictures demonstrate the effect of the lights volume num samples. Notice how the right image is cleaner.


Tip:

The more transparent the volume, the more samples it will need to render cleanly. Relatively opaque volumes can render cleanly with fewer samples.


Domelight's Volume Num Samples set to 1

Domelight's Volume Num Samples set to 512


When using Global Illumination (GI), volume noise can appear because of brute-force GI rays, too.

In the scene below we disabled our domelight, made the ground plane emissive and enabled brute-force GI. The effect is GI lighting coming from below the bunny. Notice how the image using more GI rays is cleaner.


Brute-force GI with 16 rays

Brute-force GI with 512 rays