next up previous contents
Next: 9.3 Reflections and Refractions Up: 9 Scene Realism Previous: 9.1 Motion Blur

Depth of Field

OpenGL's perspective projections simulate a pinhole camera; everything in the scene is in perfect focus. Real lenses have a finite area, which causes only objects within a limited range of distances to be in focus. Objects closer or farther from the camera are progressively more blurred.

The accumulation buffer can be used to create depth of field effects by jittering the eye point and the direction of view. These two parameters change in concert, so that one plane in the frustum doesn't change. This distance from the eyepoint is thus in focus, while distances nearer and farther become more and more blurred.

 

table1897

To create depth of field blurring, the perspective transform changes described in the antialiasing section are expanded somewhat. This code modifies the frustum as before, but adds in an additional offset. This offset is also used to change the modelview matrix; the two acting together change the eyepoint and the direction of view:

void frustum_depthoffield(GLdouble left, GLdouble right,
                        GLdouble bottom, GLdouble top,
                        GLdouble near, GLdouble far,
                        GLdouble xoff, GLdouble yoff,
                        GLdouble focus)
{
    glFrustum(left - xoff * near/focus,
                right - xoff * near/focus,
                top - yoff * near/focus,
                bottom - yoff * near/focus,
                near, far);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glTranslatef(-xoff, -yoff);
}

The variables xoff and yoff now jitter the eyepoint, not the entire scene. The focus variable describes the distance from the eye where objects will be in perfect focus. Think of the eyepoint jittering as sampling the surface of a lens. The larger the lens, the greater the range of jitter values, and the more pronounced the blurring. The more samples taken, the more accurate a sampling of the lens. You can use the jitter values given in the scene antialiasing section.

This function assumes that the current matrix is the projection matrix. It sets the frustum, then sets the modelview matrix to the identity, and loads it with a translation. The usual modelview transformations could then be applied to the modified modelview matrix stack. The translate would become the last logical transform to be applied.



David Blythe
Thu Jul 17 21:24:28 PDT 1997