Lens Shaders

Lens shaders are called for primary rays from the camera. The camera is normally a simple pinhole camera. A lens shader modifies the origin and direction of a primary ray from the camera. More than one lens shader may be attached to the camera; each modifies the origin and direction calculated by the previous one. By convention, all rays up to and including the one leaving the last lens are called "primary rays". The origin and direction input parameters can be found in the state, in the origin and dir variables. The outgoing ray is cast with mi_trace_eye, whose return color may be modified before the shader itself returns. Lens shaders are called recursively; a call to mi_trace_eye will call the next lens shader if there is another one.

Here is a sample lens shader that implements a fish-eye lens:

miBoolean fisheye(
    miColor         *result,
    miState         *state,
    void            *paras)
    miVector        camdir, dir;
    miScalar        x, y, r, t;

    mi_vector_to_camera(state, &camdir, &state->dir);
    t = state->camera->focal / -camdir.z /
    x = t * camdir.x;
    y = t * camdir.y * state->camera->aspect;
    r = x * x + y * y;
    if (r < 1) {
            dir.x = camdir.x * r;
            dir.y = camdir.y * r;
            dir.z = -sqrt(1 - dir.x*dir.x - dir.y*dir.y);
            mi_vector_from_camera(state, &dir, &dir);
            return(mi_trace_eye(result, state, &state->org, &dir));
    } else {
            result->r = result->g =
            result->b = result->a = 0;

This shader does not take the image aspect ratio into account, and is not physically correct. It merely bends rays away from the camera axis depending on their angle to the camera axis. Rays that fall outside the circle that touches the image edges are set to black (note that alpha is also set to 0). The rays are bent according to the square of the angle, which approaches the physically correct deflection for small values of π. This example shader has no shader parameters, which is why the type of the paras parameter is void *.

Be sure to derive the ray origin from state→org, not state→point, which is undefined in lens shaders and can cause incorrect and empty or extremely noisy pictures.

Copyright © 1986, 2013 NVIDIA Corporation