Keywords: main

Next: 3.16 Lens Shaders Up: 3. Using and Writing Previous: 3.14 Photon Shaders

# 3.15 Photon Emitter Shaders

Photon emitter shaders are used in the photon tracing phase to control the emission of photons from the light sources. There exists a number of built-in photon emitters that handle the following types of light sources:

- Point lights: emit photons with equal flux in all directions around the point light.

- Spot lights: emit photons with equal flux within the cone specified by the spotlight parameters.

- Directional lights: emit photons with equal radiance (based on the energy). Since a directional light source is strictly non-physical, the energy concepts are different from the other light sources.

- Disc area lights: emit photons from different points on the disc in directions based on a cosine distribution.

- Rectangle area lights: emit photons from different points on the rectangle in directions based on a cosine distribution.

- Sphere area lights: emit photons with equal flux from the surface of the sphere based on a cosine distribution at each surface point.

- Cylinder area lights: emit photons with equal flux from the surface of the cylinder based on a cosine distribution. No photons are emitted from the two disc-shaped ``ends'' of the cylinder.

Unless there are good reasons, these light sources should be used since they are well optimized. This is particularly true for the point light and sphere light which use a projection map to limit the emission of photons to the directions in which caustic generating objects are found. The appropriate built-in photon emitters are automatically applied if no photon emitter is specified in the light source definition.

If more complex light sources are needed, it can be necessary to write a specialized shader. For example, this could be necessary for a spot light that should support intensity fading near the edges of the cone. Note that the light emitter shader is not called if the light has zero energy; such lights are ignored by mental ray during photon tracing.

An example of a simple point light that emits photons uniformly in all directions around the current point is given in the following shader3.1. The shader receives information about the light source from state - > light_instance.

         #include <stdio.h>
         #include <math.h>
         #include "shader.h"

         int point_emitter_version() {return(1);}

         void point_emitter_init(
            miState         *state,
            void            *p,
            miBoolean       *inst_init_req)
         {
            miTag           light_tag;
            miMatrix        *T;

            if (!p)
                *inst_init_req = miTRUE;
            else {
                miVector org, *torg;
                torg = mi_mem_allocate(sizeof(miVector));

                mi_query(miQ_INST_ITEM, state,
                         state->light_instance, &light_tag);
                mi_query(miQ_INST_LOCAL_TO_GLOBAL, state,
                         state->light_instance, &T);
                mi_query(miQ_LIGHT_ORIGIN, state,
                         light_tag, &org);

                mi_point_transform(torg, &org, *T);
                state->shader->user.p = torg;
            }
         }

         void point_emitter_exit(
            miState         *state,
            void            *p)
         {
            if (state->shader->user.p && p) {
                mi_mem_release(state->shader->user.p);
                state->shader->user.p = NULL;
            }
         }

         miBoolean point_emitter(
            miColor         *energy,
            miState         *state,
            void            *p)
         {
            state->org = *(miVector *)state->shader->user.p;
            do
                mi_scattering_dir_diffuse(&state->dir, state);

            while ((state->dir.x * state->dir.x +
                    state->dir.y * state->dir.y +
                    state->dir.z * state->dir.z) > 1.0);

            mi_vector_normalize(&state->dir);
            mi_photon_light(energy, state);
            return(miTRUE);
         }

This shader does not take any parameters. Instead it extracts all information about the light source with mi_query. This shader can be attached to a light definition using the `photon` statement. Note the choice of direction using mi_scattering_dir_diffuse and rejection sampling: instead of limiting the computed directions to points in a circle, rectangular directions are computed and rejected if they fall outside the circle. This is more efficient than computing polar coordinates, adjusting for uniform density, and converting to rectangular coordinates. The org and dir or any other ray state variables are undefined when the shader is called, the shader must come up with its own directions.

If a photon emitter shader returns `miFALSE`, photon emission from the current light source is aborted at that point and no more photons are cast from this light source. It is recommended that photon emitter shaders return `miTRUE` only if they called mi_photon_light because otherwise mental ray will keep calling the shader for a long time without ever storing a photon.

#### Footnotes

... shader3.1
  This is just a simple example shader -- the builtin point light emitter is much more efficient.

Next: 3.16 Lens Shaders Up: 3. Using and Writing Previous: 3.14 Photon Shaders