Density

### 6.8.3 Density

Particles of media are normally distributed in constant density throughout the media. However the `density` statement allows you to vary the density across space using any of POV-Ray's pattern functions such as those used in textures. If no `density` statement is given then the density remains a constant value of 1.0 throughout the media. More than one `density` may be specified per `media` statement. See "Multiple Density vs. Multiple Media". The syntax for `density` is:

    DENSITY:
        density
        {
            [DENSITY_IDENTIFIER]
            [DENSITY_TYPE]
            [DENSITY_MODIFIER...]
        }
    DENSITY_TYPE:
        PATTERN_TYPE | COLOR
    DENSITY_MODIFIER:
        PATTERN_MODIFIER | DENSITY_LIST | color_map { COLOR_MAP_BODY } |
        colour_map { COLOR_MAP_BODY } | density_map { DENSITY_MAP_BODY }

The `density` statement may begin with an optional density identifier. All subsequent values modify the defaults or the values in the identifier. The next item is a pattern type. This is any one of POV-Ray's pattern functions such as `bozo`, `wood`, `gradient`, `waves`, etc. Of particular usefulness are the `spherical`, `planar`, `cylindrical`, and `boxed` patterns which were previously available only for use with our discontinued `halo` feature. All patterns return a value from 0.0 to 1.0. This value is interpreted as the density of the media at that particular point. See "Patterns" for details on particular pattern types. Although a solid COLOR pattern is legal, in general it is used only when the `density` statement is inside a `density_map`.

#### 6.8.3.1 General Density Modifiers

A `density` statement may be modified by any of the general pattern modifiers such as transformations, `turbulence` and `warp`. See "Pattern Modifiers" for details. In addition there are several density-specific modifiers which can be used.

#### 6.8.3.2 Density with color_map

Typically a `media` uses just one constant color throughout. Even if you vary the density, it is usually just one color which is specified by the `absorption`, `emission`, or `scattering` keywords. However when using `emission` to simulate fire or explosions, the center of the flame (high density area) is typically brighter and white or yellow. The outer edge of the flame (less density) fades to orange, red, or in some cases deep blue. To model the density-dependent change in color which is visible, you may specify a `color_map`. The pattern function returns a value from 0.0 to 1.0 and the value is passed to the color map to compute what color or blend of colors is used. See "Color Maps" for details on how pattern values work with `color_map`. This resulting color is multiplied by the `absorption`, `emission` and `scattering` color. Currently there is no way to specify different color maps for each media type within the same `media` statement.

Consider this example:

      media{
        emission 0.75
        scattering {1, 0.5}
        density { spherical
          color_map {
            [0.0 rgb <0,0,0.5>]
            [0.5 rgb <0.8, 0.8, 0.4>]
            [1.0 rgb <1,1,1>]
          }
        }
      }

The color map ranges from white at density 1.0 to bright yellow at density 0.5 to deep blue at density 0. Assume we sample a point at density 0.5. The emission is 0.75*<0.8,0.8,0.4> or <0.6,0.6,0.3>. Similarly the scattering color is 0.5*<0.8,0.8,0.4> or <0.4,0.4,0.2>.

For block pattern types `checker`, `hexagon`, and `brick` you may specify a color list such as this:

      density{
        checker
        density {rgb<1,0,0>}
        density {rgb<0,0,0>}
      }

See "Color List Pigments" which describes how `pigment` uses a color list. The same principles apply when using them with `density`.

#### 6.8.3.3 Density Maps and Density Lists

In addition to specifying blended colors with a color map you may create a blend of densities using a `density_map`. The syntax for a density map is identical to a color map except you specify a density in each map entry (and not a color).

The syntax for `density_map` is as follows:

    DENSITY_MAP:
        density_map { DENSITY_MAP_BODY }
    DENSITY_MAP_BODY:
        DENSITY_MAP_IDENTIFIER | DENSITY_MAP_ENTRY...
    DENSITY_MAP_ENTRY:
        [ Value DENSITY_BODY ]

Where `Value` is a float value between 0.0 and 1.0 inclusive and each DENSITY_BODY is anything which can be inside a `density{...}` statement. The `density` keyword and `{}` braces need not be specified.

Note: the `[]` brackets are part of the actual DENSITY_MAP_ENTRY. They are not notational symbols denoting optional parts. The brackets surround each entry in the density map.

There may be from 2 to 256 entries in the map.

Density maps may be nested to any level of complexity you desire. The densities in a map may have color maps or density maps or any type of density you want.

Entire densities may also be used with the block patterns such as `checker`, `hexagon` and `brick`. For example...

      density {
        checker
        density { Flame scale .8 }
        density { Fire scale .5 }
      }

Note: in the case of block patterns the `density` wrapping is required around the density information.

A density map is also used with the `average` density type. See "Average" for details.

You may declare and use density map identifiers but the only way to declare a density block pattern list is to declare a density identifier for the entire density.

#### 6.8.3.4 Multiple Density vs. Multiple Media

It is possible to have more than one `media` specified per object and it is legal to have more than one `density` per `media`. The effects are quite different. Consider this example:

      object {
        MyObject
        pigment { rgbf 1 }
        interior {
          media {
            density { Some_Density }
            density { Another_Density }
          }
        }
      }

As the media is sampled, calculations are performed for each density pattern at each sample point. The resulting samples are multiplied together. Suppose one density returned `rgb<.8,.8,.4>` and the other returned `rgb<.25,.25,0>`. The resulting color is `rgb<.2,.2,0>`.

Note: in areas where one density returns zero, it will wipe out the other density. The end result is that only density areas which overlap will be visible. This is similar to a CSG intersection operation. Now consider

      object {
        MyObject
        pigment { rgbf 1 }
        interior {
          media {
            density { Some_Density }
          }
          media {
            density { Another_Density }
          }
        }
      }

In this case each media is computed independently. The resulting colors are added together. Suppose one density and media returned `rgb<.8,.8,.4>` and the other returned `rgb<.25,.25,0>`. The resulting color is `rgb<1.05,1.05,.4>`. The end result is that density areas which overlap will be especially bright and all areas will be visible. This is similar to a CSG union operation. See the sample scene `scenes\interior\media\media4.pov` for an example which illustrates this.