2.7. Global Settings
Prev | Chapter 2. MegaPOV References | Next

## 2.7. Global Settings

### 2.7.1. Film exposure simulation

### Kari Kivisalo

This addition simulates decrease of reactive chemicals in film emulsion during exposure. The areas that have received more light react less than other areas. Useful for high contrast scenes as it brings up the dark areas and limit bright areas.

There are two new keywords in the `global_settings` block:

    exposure FLOAT
    exposure_gain FLOAT

where `exposure_gain` is optional and has default value 1. Both parameters have to be greater than 0 to influence rendering.

`exposure` can be thought as film speed, aperture and exposure time multiplied together. The value is not absolute. If the light source intensities in the scene are multiplied by 10 and exposure value is divided by 10 the resulting image will be the same.

`exposure_gain` can be used to brighten scenes with low maximum intensity when also low exposure value is used.

The equation for such behavior of color used in MegaPOV is:

color = exposure_gain * (1 - exp( - exposure * color )).

Table 2.3. Exposure influence comparison

no exposure used | `exposure` `1.6`

Example 2.10. Various values for film exposure simulations

Examples which map range 0-1 to range 0-1 with increasing amount of compression:

    exposure 0.05 exposure_gain 20   // almost linear
    exposure 0.2  exposure_gain 5.5
    exposure 0.5  exposure_gain 2.5
    exposure 1    exposure_gain 1.6
    exposure 10   exposure_gain 1
    exposure 100  exposure_gain 1    // high compression

### 2.7.2. Radiosity

#### 2.7.2.1. Cache file

### Włodzimierz ABX Skiba

In POV-Ray™ 3.5 and earlier temporary files with cache of radiosity were named the same for every frame in the animation rendering. Since MegaPOV 1.0 the name of this file is concatenated from the name of the currently rendered image. Together with `Frame_Step` (see Section 2.1.1, “Frame_Step”) and this addition it is finally possible to start two parallel processes with radiosity rendering over one source.

#### 2.7.2.2. Custom radiosity sampling directions

### Christoph Hormann

The radiosity function in POV-Ray™ 3.5 uses an internal table of directions for the rays that are traced from a sampling point to determine the irradiance at that point. This patch allows to select alternative sets of sample ray directions. This can help both to overcome the limit for maximum `count` of 1600 as well as improve the quality of results at lower count values.

The syntax description of this feature is:

    RADIOSITY_ITEMS:
        ...
        [ samples SAMPLES_ITEMS ]

    SAMPLES_ITEMS:
        INT_SAMPLES_TYPE |
        {
          SAMPLES_COUNT,
          VECTOR_DIRECTION, ...
          [weight INT_WEIGHT_TYPE]
        }

##### 2.7.2.2.1. internally generated directions

MegaPOV contains an internal generator for sample direction using the halton sequence written by Mael. It is activated by adding:

    samples 1

to the `radiosity{}` block. The default value (0) uses the old internal direction table.

Table 2.4. internal sequence

50 rays | 300 rays | 1600 rays

Table 2.5. halton sequence

50 rays | 300 rays | 1600 rays

##### 2.7.2.2.2. user defined directions

The sample ray directions can also be defined directly in the scene file:

    samples {
      300, // number of directions given
      <0.78080, -0.36618, 0.50622>,
      <-0.26409, -0.01064, 0.96444>,
      ...
    }

A number of sample direction sets is coming with MegaPOV as include files.

The coordinate system for these sample ray directions is relative to the surface at the sample position. The z-Axis points in normal direction. All directions should be in the upper hemisphere (z coordinate >0).

An optional `weight` parameter allows to weight the sample intensity with `cos(theta)` where `theta` is the angle between the normal vector and the ray direction. The sample ray directions should have a density distribution according to this function. If a uniform distribution is used instead `weight 1` would weight the sample rays to compensate this. The default is 0 which turns off special weighting.

#### 2.7.2.3. Randomized radiosity sampling directions

### Christoph Hormann

This patch is based on an idea by Michael Andrews. Normally the distribution of radiosity rays is identical for all sample points. This patch rotates the sample set around the vertical axis by a random angle for each sample taken. This can help to reduce artefacts in some cases.

This patch is activated the following way:

    radiosity {
      ...
      randomize on
    }

| Note
Since this feature uses a random number for the sample direction rotation it is not safe to use it in animations. Also a partial render of a scene will produce different results than rendering the whole scene.

### 2.7.3. Mechanics simulation patch

### Christoph Hormann

The mechanics simulation system is integrated into the POV-Ray™ rendering system. The simulation parameters are set in the `global_settings{}` block of the scene file. While parsing the scene MegaPOV calculates the simulation exactly where it occurs in the file. This way the simulation can interact with the scene by using objects, functions and values set before the `mechsim{}` block in the scene file. But additionally the simulation data can also be used in the scene later on for placing objects according to the simulation results.

#### 2.7.3.1. The simulation settings

This patch introduces a new block in the `global_settings{}` section of the POV-Ray™ scene file.

The complete syntax description of this block is:

    MECHSIM:
        mechsim { [MECHSIM_ITEMS...] }
    MECHSIM_ITEM:
        method INTEGER | bounding INTEGER |
        gravity VECTOR | time_step FLOAT |
        step_count INTEGER | time FLOAT | start_time FLOAT |
        end_time FLOAT
        environment { ENVIRONMENT_DEFINITION [ENVIRONMENT_ITEMS...] } |
        interaction { INTERACTION_DEFINITION ... } |
        field { FIELD_DEFINITION ... } |
        attach { ATTACH_DEFINITION ... } |
        collision { COLLISION_TOGGLE [COLLISION_ITEMS...] } |
        topology { [GROUP_DEFINITIONS...] [TOPOLOGY_ITEMS...]
                   [save_file FILE_NAME [Type]] }
    ENVIRONMENT_DEFINITION:
        function [(IDENT_LIST)] { FUNCTION_ITEMS } | object OBJECT
    ENVIRONMENT_ITEM:
        stiffness FLOAT | damping FLOAT | friction FLOAT [, FLOAT] |
        method INTEGER
    INTERACTION_DEFINITION:
        function [(IDENT_LIST)] { FUNCTION_ITEMS }
    FIELD_DEFINITION:
        function { SPECIAL_COLOR_FUNCTION }
    ATTACH_DEFINITION:
        function { SPLINE }
    COLLISION_TOGGLE:
        [INT_MASS_MASS [, INT_MASS_FACE [, INT_CONNECTION_CONNECTION]]]
    COLLISION_ITEM:
        stiffness FLOAT | damping FLOAT | friction FLOAT [, FLOAT]
    GROUP_DEFINITION:
        group [(INT_GROUP_INDEX)] { TOPOLOGY_ITEMS... }
    TOPOLOGY_ITEM:
        mass { V_POSITION, V_VELOCITY, F_RADIUS
               mass FLOAT | density FLOAT [attach INTEGER] [fixed BOOL] } |
        connection { INDEX1, INDEX2 [stiffness FLOAT] [damping FLOAT]
                     [length FLOAT] } |
        face { INDEX1, INDEX2, INDEX3 } |
        load_file FILE_NAME

##### 2.7.3.1.1. The general settings

Some general parameters can be given in the top level of the `mechsim{}` section.

The default values are:

`method` : `1`

`bounding` : `0`

`gravity` : `<0, 0, 0>`

`time_step` : `0.1`

`step_count` : `10`

###### 2.7.3.1.1.1. method

Selects the integration method used for solving the equations of movement.

Possible values are:

- `1` (`MECHSIM_METHOD_EULER`) simple forward Euler integration method
- `2` (`MECHSIM_METHOD_HEUN`) second order (Heun) integration method
- `3` (`MECHSIM_METHOD_RUNGE_KUTTA`) fourth order Runge Kutta integration method
- `4` (`MECHSIM_METHOD_GRADIENT`) gradient descent method

Method 1 is a first order integration method also known as explicit Euler method. With the differential equations of movement written as:

`y` being the state of the system (positions and velocities) and the initial conditions `y(t0)=y0` the Euler method can be written as:

Method 2 is a second order integration method known as Heun's method. Its formula is:

Method 3 is a fourth order integration method known as the classical Runge-Kutta method:

###### 2.7.3.1.1.2. bounding

Selects the bounding method to speed up collision detections.

Possible values are:

- `0` (`MECHSIM_COLLISION_BOUNDING_NO`) no bounding system
- `1` (`MECHSIM_COLLISION_BOUNDING_AUTO`) automatically select method 0, 2 or 3 depending on complexity
- `2` (`MECHSIM_COLLISION_BOUNDING_BOX`) speed up using bounding boxes
- `3` (`MECHSIM_COLLISION_BOUNDING_HASH`) speed up using spatial hashing

The bounding techniques have been implemented by Daniel Jungmann and are in an experimental state. The internal workings as well as the use are likely to change in future versions.

###### 2.7.3.1.1.3. gravity

Applies an overall constant gravitational force to all masses.

A vector is expected, the unit is `m/s²`.

Standard earth gravity (with y=up coordinates) is:

    gravity <0, -9.81, 0>

With field functions (see Section 2.7.3.1.6, “Field forces”) non constant gravity can be simulated

###### 2.7.3.1.1.4. simulation stepping

All simulation methods use discrete time steps for calculating the simulation. There are three parameters to steer this but only two are needed to correctly define the stepping. The formula for calculating the third is:

`Step_Count = Time / Time_Step`

An optional `start_time` value allows to specify a starting time different from `0`. Changing this can influence the `attach` and `environment` function. (see Section 2.7.3.1.7, “Attaching masses” and Section 2.7.3.1.2, “The environments”) Specifying an `end_time` value instead of `time` is also possible.

| Important
Using too large time steps can lead to instability in the simulation. MegaPOV will recognize this in most cases and stop simulation with an error message but this does not mean the simulation is correct as long as no error is reported. Simulation results should always be checked for plausibility.

##### 2.7.3.1.2. The environments

Environments are shapes the simulated masses are supposed to interact with. Several of them can be created with `environment{}` blocks.

###### 2.7.3.1.2.1. The environment definition

An environment is defined either by a user defined function or an object. If both are given the function is preferred.

Apart from the default parameters (`x`, `y` and `z`) the function can have a fourth parameter supplying a time index. This way moving environment objects can be simulated.

    #declare fn_Env=function(x, y, z, tim) { z-tim }

    global_settings {
      ...
      mechsim {
        ...
        environment {
          function(x, y, z, tim) { fn_Env(x, y, z, tim) }
          ...
        }
      }
    }

###### 2.7.3.1.2.2. The environment properties

There are three parameters defining the properties of the environment:

- `stiffness` The elasticity parameter of the surface. The unit is `N/m` or `kg/s²`.

- `damping` Depending on the environment calculation method (see below) this is either a diminishing factor (<1) applied to the mass velocities at each collision or a damping constant (unit `kg/s`)

- `friction` The friction factor controls the amount of friction during collisions. An optional second parameter, the friction excess value should usually be slightly larger than 1 and causes the friction to occur already slightly above the surface. This can be helpful to obtain realistic results.

###### 2.7.3.1.2.3. The environment calculation method

There are currently two methods how the environment collisions can be calculated:

- Method 1 (`MECHSIM_ENV_METHOD_FORCE`) is force based. When a mass collides with the environment a force is applied in direction of the function gradient (with function based environments) or the surface normal (with objects). The `stiffness`, `damping` and `friction` parameters influence this force. `friction` defines the ratio between the tangential force and the normal force.

  Figure 2.1. Force based environment collisions illustration

- Method 2 (`MECHSIM_ENV_METHOD_IMPACT`) is based on impact laws. The velocity is inverted at the surface and diminished by the `damping` factor in normal direction and by the `friction` value in tangential direction. `stiffness` does not have any influence in this case.

  Figure 2.2. Impact based environment collisions illustration

  Since this method directly modifies the velocity rather than applying forces it should only be used with the first order (Euler) integration method.

With the gradient descent simulation method the method parameter does not have any effect.

##### 2.7.3.1.3. The collision settings

The collisions referred to here are not environment collisions but collisions between the simulation elements. Since detecting this kind of collision is quite computationally intensive it is turned off by default.

With three numbers at the beginning of the `collision{}` section collision can be toggled for mass-mass-collisions, mass-face-collisions and connection-connection-collisions. All these parameters are optional, the meaning of the possible values is:

- `0` (`MECHSIM_COLLISION_NONE`) No collisions of this kind are calculated.
- `1` (`MECHSIM_COLLISION_ALL`) Collisions between all simulation elements are calculated.
- `2` (`MECHSIM_COLLISION_GROUP`) Only collisions between elements of different groups are calculated.

Figure 2.3. Mass-mass collisions illustration

Figure 2.4. Mass-face collisions illustration

Figure 2.5. Connection-connection collisions illustration

Internal collisions are always calculated with forces. The same three parameters like in the environment settings can be used to specify the properties

- `stiffness` The elasticity parameter of the surface. The unit is `N/m` or `kg/s²`.
- `damping` A damping constant (unit `kg/s`)
- `friction` The friction factor controls the amount of friction during collisions. An optional second parameter, the friction excess value should usually be slightly larger than 1 and causes the friction to occur already slightly before the collision. This can be helpful to obtain realistic results.

Example 2.11. An example for a complete `collision{}` section:

    global_settings {
      ...
      mechsim {
        ...
        collision {
          2, /* mass-mass collisions between elements of different groups */
          0, /* no mass-face collisions */
          0  /* no connection-connection collisions */
          stiffness 20000
          damping 4000
          friction 0.2, 1.01
        }
      }
    }

##### 2.7.3.1.4. The topology

The `topology{}` section is the central part of the whole simulation settings. Here the simulation elements, their positions and properties, can be defined.

###### 2.7.3.1.4.1. The topology items

There are three topology items: masses, connections and faces. Each of them has several parameters that can be set.

The `mass` block defines a point mass. These are the central elements of the simulation. Their movement is calculated by the simulation system.

The `mass` block contains the following elements:

- The first item is a vector specifying the position of them mass (unit: `m`).
- The second item, also a vector, represents the velocity of them mass (unit: `m/s`).
- The third item is a float standing for the radius of the mass (unit: `m`). This radius is only used in collision calculations (see Section 2.7.3.1.3, “The collision settings”). Otherwise the mass behaves as a point mass.

In addition either the `mass` (unit: `kg`) or the `density` (unit: `kg/m³`) of the element has to be given. If `density` is specified the resulting mass is calculated automatically. An optional boolean parameter (`fixed`) prevents the mass from moving if set to `true`.

A complete example for a mass definition:

    mass {
      <0, 0, 1>, /* position */
      <1, 0, 0>, /* velocity */
      0.1        /* radius */
      density 600
      // mass 2
      // fixed true
    }

The `connection` block defines a connection between two point masses. It can have elastic and dissipative properties.

The first two elements of this block are integer numbers specifying the indices of the masses to connect.

There are three optional parameters: The `stiffness` value specifies the elasticity of the connection (unit `N/m` or `kg/s²`). `damping` the velocity proportional damping factor (unit `kg/s`). The default value for both of these is zero. The third parameter allows to specify a relaxed length of the connection. If it is not specified the distance of the two masses is used for this property.

A complete example for a connection definition:

    global_settings {
      ...
      mechsim {
        ...
        topology {
          mass { ... }  /* mass with index 0 */
          mass { ... }  /* mass with index 1 */

          connection {
            0,          /* index of the first mass */
            1           /* index of the second mass */
            stiffness 10000
            damping 2000
            // length 0.5
          }
          ...
        }
      }
    }

The `face` block defines a triangular face between three point masses. It is used for collision calculations (see Section 2.7.3.1.3, “The collision settings”) and can be useful for generating a mesh from the simulation data for display.

There are three integer numbers in the block, the indices of the masses forming the face.

A complete example for a face definition:

    global_settings {
      ...
      mechsim {
        ...
        topology {
          mass { ... }  /* mass with index 0 */
          mass { ... }  /* mass with index 1 */
          mass { ... }  /* mass with index 2 */

          face {
            0,          /* index of the first mass */
            1,          /* index of the second mass */
            2           /* index of the third mass */
          }
          ...
        }
      }
    }

###### 2.7.3.1.4.2. grouping elements

Simulation elements can be categorized into groups. The main purpose of this is to speed up collision tests. The `group` keyword can be followed by an integer number in parentheses to explicitly specify the group. Otherwise the group index is determined automatically.

    global_settings {
      ...
      mechsim {
        ...
        topology {
          mass { ... }  /* these elements are group index 0 */
          ...
          group {
            mass { ... } /* these elements are group index 1 */
          }
          group {
            mass { ... } /* these elements are group index 2 */
          }
          group (1) {
            mass { ... } /* these elements are group index 1 */
          }

          ...
        }
      }
    }

###### 2.7.3.1.4.3. saving and loading topology data

The topology data can be written to and loaded from files. For the format of these files see Section 2.7.3.3, “The simulation data file format”.

`save_file` can only be added to the main `topology{}` block. It saves the complete data after the simulation to the specified file.

`load_file` can be placed anywhere in the `topology{}` section. If placed in a group the elements in the file are added to that group. Otherwise they are are placed in groups according to group index information in the file.

The same file name can be specified for both loading and saving the data. This is especially useful for animation when the following frame simulation should start with the result of the last frame:

    global_settings {
      ...
      mechsim {
        ...
        topology {
          load_file "mechsim_data.dat"
          save_file "mechsim_data.dat"
        }
      }
    }

##### 2.7.3.1.5. Mass interaction

Masses can be set to exert forces on each other depending on the distance and the position in space. Phenomena like gravity in space and electrostatic fields can be simulated this way.

The `interaction{}` block can contain one or more user defined functions. Apart from the default parameters (`x`, `y` and `z`) the functions can have a fourth parameter that is used for the distance between the masses. The function return value defines the force exerted on both masses in opposite directions. Positive values mean attractive forces and negative values repulsion.

    #declare fn_Force=function(x, y, z, dist) { 1/(dist*dist) }

    global_settings {
      ...
      mechsim {
        ...
        interaction {
          function(x, y, z, dist) { fn_Force(x, y, z, dist) }
          ...
        }
      }
    }

##### 2.7.3.1.6. Field forces

General field like forces can be simulated using the `field{}` block. One example for such a field force is gravity although the simulation system has a special parameter for specifying such a simple constant gravity force. Much more complicated fields can be set up using this function.

The `field{}` block expects a pigment function defining the force components in the different directions. The `red` component of the pigment for the `x` direction, the `green` component for the `y` direction and `blue` for `z`. The mechsim include file contains a macro generating an appropriate pigment function from three float functions.

Example 2.12. Constant downward force in Mechanics simulation

A function for a constant downward force (in y direction) would look like:

    #include "mechsim.inc"

    global_settings {
      ...
      mechsim {
        ...
        field {
          function {
            Vector_Function(
              function {0},
              function {-1},
              function {0}
            )
          }
          ...
        }
      }
    }

Note that in contrast to the gravity parameter the fields define a force and not an acceleration. Large masses will be influenced less than small masses.

##### 2.7.3.1.7. Attaching masses

Apart from adding the `fixed` flag to masses and thereby fixing them to a certain position we can also constrain them to a certain predefined movement. Those movements are described with spline functions in the `attach{}` block.

    global_settings {
      ...
      mechsim {
        ...
        attach {
          function {
            spline {
              linear_spline
                0.0, <0,0,0>
                0.5, <1,0,0>
                1.0, <2,0,0>
              }
            }
          }
          ...
        }
      }
    }

These functions are automatically numbered starting from zero. To attach a mass to a function the `attach` parameter has to be set in the mass definition. The following mass is attached to the `attach` function with the number two:

    mass {
      <0, 0, 1>, <0, 0, 0>, 0.1
      density 600
      attach 2
    }

During the simulation the spline is evaluated at the current time value and the returned vector describes the movement of the attached masses. Note that the spline does not describe an absolute position for the masses, just their movement relative to their starting position. Attaching several masses to the same spline makes them perform a parallel movement.

#### 2.7.3.2. Accessing simulation data

The whole simulation data can be accessed anywhere in the POV-Script. This is achieved by adding new float/vector functions:

The complete syntax description of this block is:

    FLOAT_FUNCTION:
        ... | mechsim : MECHSIM_ELEMENTS
    MECHSIM_ELEMENTS:
        mass_count | connection_count | face_count |
        mass( INTEGER ) : MASS_FLOAT_ELEMENT |
        connection( INTEGER ) : CONNECTION_FLOAT_ELEMENT |
        face( INTEGER ) : FACE_FLOAT_ELEMENT
    MASS_FLOAT_ELEMENT:
        radius | mass
    CONNECTION_FLOAT_ELEMENT:
        index1 | index2 | length | stiffness | damping
    FACE_FLOAT_ELEMENT:
        index1 | index2 | index3

    VECTOR_FUNCTION:
        ... | mechsim : MECHSIM_ELEMENTS
    MECHSIM_ELEMENTS:
        mass( INTEGER ) : MASS_VECTOR_ELEMENT
    MASS_VECTOR_ELEMENT:
        position | velocity

These elements correspond to those set in the `mechsim{}` block in `global_settings{}`. The mass position and velocity are the ones that are modified during simulation. The `mass_count` `connection_count` and `face_count` values are especially useful inside the `mechsim{}` block to determine the current index:

    global_settings {
      ...
      mechsim {
        ...
        topology {
          /* part 1 */
          mass { ... }
          mass { ... }
          connection { ... }
          ...

          #declare Start_Mass_Part2=mechsim:mass_count;
          #declare Start_Connection_Part2=mechsim:connection_count;

          /* part 2 */
          mass { ... }
          mass { ... }
          connection { ... }
          ...
        }
      }
    }

The `Start_Mass_Part2` and `Start_Connection_Part2` variables can later be used to display the different parts of the simulation in different forms.

#### 2.7.3.3. The simulation data file format

The file format used by the `load_file` and `save_file` options is a text format compatible to the POV-Ray™ `#read` and `#write` directives.

The different fields in the file (referred to as elements here) are separated by commas (,) and each contain either a string, an integer or float value or a vector.

The first element is a four character string ('MSIM') identifying the mechanics simulation file format. The second element is an integer number specifying the subformat of the file. Subformat `2` was used in Sim-POV 0.1.0 and Sim-POV 0.2.0 allows to write subformat 2 and 3.

The main difference is that type 3 files contain the attach index (see Section 2.7.3.1.7, “Attaching masses”) for each mass. In addition the subformat value is followed by a float for the start time in subformat 3. When the simulation data is saved after the simulation the time index at the beginning is increased by the simulation duration. This way environments and attachments are correctly moved during animations. The subformat can be specified with an additional number after the file name string in save_file. The default subformat is `2`.

The following three integer numbers are the numbers of masses, connections and faces in the file. After them follows the data of all masses, connections and faces in that order.

For each mass there are the following elements:

- The position (vector), unit: `m`
- The velocity (vector), unit: `m/s`
- The mass (float), unit: `kg`
- The radius (float), unit: `m`
- A flag (integer) currently only containing the `fixed` value. This flag could contain other boolean values in the future (connected with logical OR) so it should be tested accordingly (`if (flag & 1)`)
- The group index (integer)
- Only for subformat 3: The attach index (integer)

For each connection:

- The index of the first mass (integer)
- The index of the second mass (integer)
- The relaxed length (float), unit: `m`
- The stiffness (float), unit: `N/m` or `kg/s²`
- The damping constant (float), unit: `kg/s`
- The group index (integer)

For each face:

- The index of the first mass (integer)
- The index of the second mass (integer)
- The index of the third mass (integer)
- The group index (integer)

The files written by MegaPOV contain a line break after the subformat value, the mass count, connection count and face count value and after each mass, connection and face.

Example 2.13. The simulation data file format

A short sample file looks like this:

    MSIM, 2,
    3,
    3,
    1,
    <-2, -2, 0>, <0, 0, 0>, 2.0, 0.05, 0, 0,
    <2, -2, 0>, <0, 0, 0>, 2.0, 0.05, 0, 0,
    <0, 2, 1>, <0, 0, 0>, 2.0, 0.05, 0, 0,
    0, 1, 0.8, 12000, 6000, 0,
    1, 2, 0.8, 12000, 6000, 0,
    0, 2, 0.8, 12000, 6000, 0,
    0, 1, 2, 0,

### 2.7.4. Post processing

### Włodzimierz ABX Skiba

Post processing allows manipulation of the color of the pixels after the rendering step is completed.

In the past, post processing of images required some third-party software (such as PhotoShop, Paint Shop Pro, or the GIMP) or older versions of MegaPOV that had implemented a few predefined effects.

MegaPOV 1.1 introduces a more generic approach to the post processing. Instead of being limited to a few predefined effects, access to the content of the rendered image through internal functions is now available for the user. By mixing these functions, any imaginable effect is possible. As an example of using these functions, some basic effects (in the form of macros) are provided with a similar syntax to the postprocessing effects included in older MegaPOV versions.

#### 2.7.4.1. Turning on the storage of data

Post processing data is stored during rendering. This data contains several components: color of the pixel, intersection point, depth, normal - in other words all the information the raytracer receives for each of the pixels. For anti-aliased images only the data from the first ray is gathered. The storage is automatically turned on after the explicit call to one of predefined macros:

    #version unofficial megapov 1.1;
    #include "pprocess.inc"
    // store data of the color and transparency
    PP_Init_Alpha_Colors_Outputs()

    // store data of the intersection point coordinates or <0,0,0>
    PP_Init_IPoint_Outputs()

    // store data of the normal at the intersection point or <0,0,0>
    PP_Init_INormal_Outputs()

    // store data of the perturbed normal at the intersection point or <0,0,0>
    PP_Init_PNormal_Outputs()

    // store the distance between camera and intersection point
    PP_Init_Depth_Output()

    // store the uv coordinates at the intersection point
    PP_Init_UV_Outputs()

    // allow access to intermediate post processing stages
    // (color and transparency received from a previous post process stage)
    PP_Init_PP_Alpha_Colors_Outputs()

| Important
When using `post_process` { }, do not forget to include the file "`pprocess.inc`" because this include file is needed to access the internal data.

| Note
If you do not need to store all the data mentioned in the macros listed above, you can pick one ore more of the dedicated internal functions mentioned further down. For example: store only the red component and the x coordinate of the intersection point for further usage. Check the content of the listed macros in the include file to find how to turn on only specific component storage.

#### 2.7.4.2. Dedicated internal functions

Macros listed in the previous section enables internal functions with the following syntax:

    // functions to access the color components and transparency
    f_output_red(x,y)
    f_output_green(x,y)
    f_output_blue(x,y)
    f_output_alpha(x,y)

    // access to the intersection point coordinates
    f_output_ipoint_x(x,y)
    f_output_ipoint_y(x,y)
    f_output_ipoint_z(x,y)

    // access to the normal vector at the intersection point
    f_output_inormal_x(x,y)
    f_output_inormal_y(x,y)
    f_output_inormal_z(x,y)

    // access to the perturbed normal vector at the intersection point
    f_output_pnormal_x(x,y)
    f_output_pnormal_y(x,y)
    f_output_pnormal_z(x,y)

    // access to the distance between camera and intersection point
    f_output_depth(x,y)

    // access to the uv coordinates at the intersection point
    f_output_u(x,y)
    f_output_v(x,y)

    // access to color and transparency of an earlier post processing stage
    f_pp_red(x,y,Ref)
    f_pp_green(x,y,Ref)
    f_pp_blue(x,y,Ref)
    f_pp_alpha(x,y,Ref)

The majority of the listed functions only need `x` and `y` parameters. These parameters are the location in the area of the rendered image. Not defined in pixels but in the range <0,1>.

Example 2.14. The internal post process function asking for red color at the middle of image

    f_output_red(0.5,0.5)

Note that <0,0> is not the value of the most top-left pixel, but the value at the top left corner of the most top left _pixel_. You have to shift it about <0.5/image_width,0.5/image_size> to hit the center of the most top left pixel. If you are not happy with the need of expressing coordinates in decimal form you can always express them in relation to the image size.

Some of the functions contain an additional `Ref` parameter. These are functions which refer to the result of the earlier calculated post processing stage. This parameter specifies to which stage we refer: 0 means output of rendering, 1 means output of first post processing, 2 means output of second postprocessing, etc.

Numbering depends on the order of appearence in the sources.

#### 2.7.4.3. Definition of the effect

Postprocessing should be defined in the `global_settings` section of the scene file like this:

    global_settings {
      post_process {
        function { ... } // calculation of red component
        function { ... } // calculation of green component
        function { ... } // calculation of blue component
        function { ... } // calculation of transparency component
        [ save_file FILENAME ]
      }
    }

Example 2.15. Post processing which does nothing (only duplicate the original image)

    global_settings {
      post_process {
        function { f_output_red(x,y) }   // calculation of red component
        function { f_output_green(x,y) } // calculation of green component
        function { f_output_blue(x,y) }  // calculation of blue component
        function { f_output_alpha(x,y) } // calculation of transparency component
        save_file "duplication.png"
      }
    }

The `post_process` block can appear a few times in the `global_settings` block. Note that saving to file is optional but only the saved blocks will be calculated. Also note that saving is always done in the same file format as the render output (regardless of the file extension).

Example 2.16. Post processing which turns the rendered image into a gray scale image

    #declare F_gray = function(r,g,b){0.297*r + 0.589*g + 0.114*b};
    global_settings {
      post_process {
        function { F_gray(f_output_red(x,y),f_output_green(x,y),f_output_blue(x,y)) }
        function { F_gray(f_output_red(x,y),f_output_green(x,y),f_output_blue(x,y)) }
        function { F_gray(f_output_red(x,y),f_output_green(x,y),f_output_blue(x,y)) }
        function { f_output_alpha(x,y) }
        save_file "grayed.png"
      }
    }

Because it could be difficult using functions to define your own post processing effects, some macros with user-friendly syntax have been added to the "`pprocess.inc`" include file. For an overview and some explanation on the parameters, (see Section 3.5.1, “Macros with effects”).

Prev | Up | Next
2.6. Textures and patterns | Home | Chapter 3. MegaPOV Include files