RC Photon Functions

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 photons 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:

photons rays
emanate from light sources emanate from the camera
call photon material shaders call material shaders
call photon volume shaders call volume shaders
call photon emission shaders call light shaders
- call lens shaders
- call environment shaders
mi_photon_light mi_trace_eye
mi_reflection_dir_specular mi_reflection_dir
mi_reflection_dir_glossy mi_reflection_dir_glossy
mi_reflection_dir_glossy_x3.4 mi_reflection_dir_glossy_x3.4
mi_reflection_dir_anisglossy mi_reflection_dir_anisglossy
mi_reflection_dir_anisglossy_x3.4 mi_reflection_dir_anisglossy_x3.4
mi_reflection_dir_diffuse mi_reflection_dir_diffuse
mi_reflection_dir_diffuse_x3.4 mi_reflection_dir_diffuse_x3.4
mi_transmission_dir_specular mi_refraction_dir
mi_transmission_dir_glossy mi_transmission_dir_glossy
mi_transmission_dir_glossy_x3.4 mi_transmission_dir_glossy_x3.4
mi_transmission_dir_anisglossy mi_transmission_dir_anisglossy
mi_transmission_dir_anisglossy_x3.4 mi_transmission_dir_anisglossy_x3.4
mi_transmission_dir_diffuse mi_transmission_dir_diffuse
mi_transmission_dir_diffuse_x3.4 mi_transmission_dir_diffuse_x3.4
mi_scattering_dir_diffuse mi_scattering_dir_diffuse
mi_scattering_dir_directional mi_scattering_dir_directional
mi_scattering_pathlength mi_scattering_pathlength
mi_photon_reflection_specular mi_trace_reflection
mi_photon_reflection_glossy -
mi_photon_reflection_diffuse -
mi_photon_transmission_specular mi_trace_refraction
mi_photon_transmission_glossy -
mi_photon_transmission_diffuse -
mi_photon_transparent mi_trace_transparent
mi_photon_volume_scattering -
mi_store_photon mi_compute_irradiance,
mi_store_volume_photon mi_compute_volume_irradiance,

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 shaders 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