The functions in this section implement *photon tracing*.
They are to be used in photon
shaders. If caustics or
global illumination are enabled,
rendering distinguishes two phases: **photon tracing**
and scanline rendering/ray tracing. Photon tracing is done
first. It sends **photon**s
from certain light sources into
the scene. When a photon hits an object, the object's
**photon shader** is called, which
then gets the opportunity to absorb the photon or use one of the
*mi_photon_** functions to let the photon continue. The photon
functions can be used only in photon shaders. Photon shaders may
not use regular ray tracing
functions such as *mi_trace_reflection*.

There are three main categories of photon tracing: specular, glossy, and diffuse. These terms define the distribution of the secondary photons in terms of the amount of scattering. Polished surfaces like chrome or clear glass are specular; unpolished surfaces such as aluminum or lightly frosted glass are glossy, and surfaces with no directional reflection or refraction such as paper are diffuse.

Photon tracing and ray tracing are similar in many respects and use similar function calls. Although the operation underneath is quite different (tracing photons vs. tracing rays), a table of the operations in each phase shows the similarity as far as the shaders are concerned:

There are three *mi_photon_reflection_** functions and
three *mi_photon_refraction_** functions (as well as a
function for transparency and one for volume scattering). Why not
just one reflection function and one transmission function, similar
to *mi_trace_reflection*
and *mi_trace_refraction*?

The reason is that mental ray needs to know what type of reflections and transmissions the photon has undergone (its "path history") to determine which photon map to store it in, when not to store the photon, and when to terminate the photon path.

The photon reflection and transmission functions all follow the
same pattern: first they check whether the intersected object is a
caustic generator, if tracing caustic photons. If the object is not
a caustic generator, the photon is not traced further and
`miFALSE` is returned. A similar check is made for
global illumination generating objects if
tracing global illumination photons. Then a new state is set up
with the appropriate ray type, reflection and refraction level,
origin and direction (and the volume in the transmission case).

Photon shaders, photon volume
shaders, and **photon
emission shader**s are optional; if one is missing, mental ray
uses built-in defaults. The default photon shader absorbs all
photons, the default photon volume shader behaves like empty space,
and the default photon emission shader behaves like a point
light source emitting photons
uniformly in all directions (that have a chance of contributing
illumination - but this is only an optimization).

Photon shaders can
use the function *mi_choose_scatter_type* to select
which type of reflection or transmission the photon should undergo
next. *mi_choose_scatter_type* chooses a
scatter type (reflection or transmission, diffuse, glossy, or
specular) or absorption. The choice is made with probabilities
depending on the scattering coefficients and the transparency. The
scattering type with the highest scattering coefficients has the
highest probability.

In the following, *d* denotes diffuse, *g* denotes
glossy, and *s* denotes specular, and the indices *r*,
*g*, and *b* mean red, green, and blue, respectively.
Each of the nine scattering coefficients (specular R, G, B, glossy
R, G, B, diffuse R, G, B) and the transparency must be in the range
[0…1]. Furthermore, the RGB scattering coefficients must
each add up to a total RGB value of (1, 1, 1).

If these conditions are not met, the coefficients are adjusted so that they are met, and a warning is given (once). To find the probability for scattering (that is, choosing one of the six types of reflection or transmission), mental ray adds the red, green, and blue coefficients for diffuse, glossy, and specular. The largest component of the resulting compound RGB value is the probability for scattering. (Remember that the RGB sums cannot exceed 1.0.)

If a photon is not scattered, it is absorbed, so the absorption probability is 1.0 minus the the scattering probability.

If the photon is not absorbed, the probability for diffuse transmission is the sum of the diffuse RGB components, divided by the sum of all nine components (diffuse, glossy, and specular R, G, and B), and multiplied by the transparency.

The probability for diffuse reflection is the same, except that the component quotient is multiplied by 1.0 minus transparency instead of transparency.

Similar for glossy and specular reflection and transmission. If a certain scattering type is chosen, the three scattering coefficients (r, g, b) for that type of scattering are adjusted following the "Russian roulette" method. Note that glossy and diffuse scattering will not be chosen if caustics are being simulated - only specular scattering (or absorption) is possible then.

The connection between the photon tracing
and ray tracing phases is the
*mi_compute_irradiance* function. It
allows material shaders (during
image rendering) to get the caustics or
global illumination color using the
photons that were stored in the photon tracing phase. The function
*mi_compute_volume_irradiance* is
similar, but computes irradiance
in a volume using the photons stored in the volume.

This distinction is still valid if
ray tracing is disabled and mental ray
is reduced to scanline rendering
in the second phase. For the purposes of
photon tracing, scanline rendering can
be considered a "ray tracing emulation" mode that achieves similar
effects but never actually traces a ray, at the cost of not being
able to control the ray direction. For example, if the `trace
off` statement or `-trace off` command-line option is
specified, it is still possible to generate caustics,
but the second phase will be
unable to compute raytraced reflections and refractions.

miBoolean mi_photon_light( miColor *energy, miState *state)

traces a photon from a
light source into the scene. The
photon origin is `state→org`

and the direction is
`state→dir`

. This function should be used only in
photon emitting shaders.

miBoolean mi_photon_reflection_specular( miColor *energy, miState *state, miVector *direction)

traces a specularly reflected photon with *energy* in
direction *direction*. This function may be used only in
photon shaders.

miBoolean mi_photon_reflection_glossy( miColor *energy, miState *state, miVector *direction)

traces a glossily reflected photon with *energy* in
direction *direction*. This function may be used only in
photon shaders.

miBoolean mi_photon_reflection_diffuse( miColor *energy, miState *state, miVector *direction)

traces a diffusely reflected photon with *energy* in
direction *direction*. This function may be used only in
photon shaders.

miBoolean mi_photon_transmission_specular( miColor *energy, miState *state, miVector *direction)

traces a specularly transmitted photon with *energy* in
direction *direction*. This function may be used only in
photon shaders.

miBoolean mi_photon_transmission_glossy( miColor *energy, miState *state, miVector *direction)

traces a glossily transmitted photon with *energy* in
direction *direction*. This function may be used only in
photon shaders.

miBoolean mi_photon_transmission_diffuse( miColor *energy, miState *state, miVector *direction)

traces a diffusely transmitted photon with *energy* in
direction *direction*. This function may be used only in
photon shaders.

miBoolean mi_photon_transparent( miColor *energy, miState *state)

traces a specularly transmitted photon with *energy* in the
direction indicated by the state (the same direction as the
previous direction). This function may be used only in
photon shaders.

miBoolean mi_photon_volume_scattering( miColor *energy, miState *state, miVector *dir);

traces a photon, scattered by a volume, with *energy* in
direction *direction*. This function may be used only in
photon shaders.

void mi_store_photon( miColor *energy, miState *state)

*mi_store_photon*
stores a photon with the given
*energy* in the photon map
at the intersection point given in `state→point`

.
Only photons with non-zero energy are stored. Photons should only
be stored at surfaces which have a diffuse component in order to
limit the storage costs and reduce the rendering time. This
function may be used only in photon
shaders.

void mi_store_volume_photon( miColor *energy, miState *state)

This function is equivalent to the previous, except that it is used to store a photon in a volume instead of on a surface. It is used for volume caustics and volume scattering (such as volumic light beams and clouds).

Copyright © 1986, 2013 NVIDIA Corporation