next up previous contents
Next: 14.2 Motion Blur Up: 14 Special Effects Previous: 14 Special Effects   Contents

14.1 Dissolves with Stencil

Stencil buffers can be used to mask selected pixels on the screen. This allows for pixel by pixel compositing of images. You can draw geometry or arrays of stencil values to control, per pixel, what is drawn into the color buffer. One way to use this capability is to composite multiple images.

A common film technique is the ``dissolve'', where one image or animated sequence is replaced with another, in a smooth sequence. The stencil buffer can be used to implement arbitrary dissolve patterns. The alpha planes of the color buffer and the alpha function can also be used to implement this kind of dissolve, but using the stencil buffer frees up the alpha planes for motion blur, transparency, smoothing, and other effects.

The basic approach to a stencil buffer dissolve is to render two different images, using the stencil buffer to control where each image can draw to the framebuffer. This can be done very simply by defining a stencil test and associating a different reference value with each image. The stencil buffer is initialized to a value such that the stencil test will pass with one of the images' reference values, and fail with the other. An example of a dissolve part way between two images is shown in Figure 80.


% latex2html id marker 16535
\fbox{\begin{tabular}{c}
\vrule width 0pt height 0....
... Figure \thefigure . Using Stencil to Dissolve Between Images}\\
\end{tabular}}

At the start of the dissolve (the first frame of the sequence), the stencil buffer is all cleared to one value, allowing only one of the images to be drawn to the framebuffer. Frame by frame, the stencil buffer is progressively changed (in an application defined pattern) to a different value, one that passes only when compared against the second image's reference value. As a result, more and more of the first image is replaced by the second.

Over a series of frames, the first image ``dissolves'' into the second, under control of the evolving pattern in the stencil buffer.

Here is a step-by-step description of a dissolve.

59.
Clear the stencil buffer with glClearGL_ STENCIL_BUFFER_BIT(GL_ STENCIL_BUFFER_BIT).
60.
Disable writing to the color buffer, using glColorMaskGL_ FALSE, GL_ FALSE, GL_ FALSE, GL_ FALSE(GL_ FALSE, GL_ FALSE, GL_ FALSE, GL_ FALSE).
61.
If the values in the depth buffer should not change, use glDepthMaskGL_ FALSE(GL_ FALSE).

For this example, we'll have the stencil test always fail, and set the stencil operation to write the reference value to the stencil buffer. Your application will also need to turn on stenciling before you begin drawing the dissolve pattern.

62.
Turn on stenciling; glEnableGL_ STENCIL_TEST(GL_ STENCIL_TEST).
63.
Set stencil function to always fail; glStencilFuncGL_ NEVER, 1, 1(GL_ NEVER, 1, 1).
64.
Set stencil op to write 1 on stencil test failure; glStencilOpGL_ REPLACE, GL_ KEEP, GL_ KEEP(GL_ REPLACE, GL_ KEEP, GL_ KEEP).
65.
Write the dissolve pattern to the stencil buffer by drawing geometry or using glDrawPixels().
66.
Disable writing to the stencil buffer with glStencilMaskGL_ FALSE(GL_ FALSE).
67.
Set stencil function to pass on 0; glStencilFuncGL_ EQUAL, 0, 1(GL_ EQUAL, 0, 1).
68.
Enable color buffer for writing with glColorMaskGL_ TRUE, GL_ TRUE, GL_ TRUE, GL_ TRUE(GL_ TRUE, GL_ TRUE, GL_ TRUE, GL_ TRUE).
69.
If you're depth testing, turn depth buffer writes back on with glDepthMask().
70.
Draw the first image. It will only be written where the stencil buffer values are 0.
71.
Change the stencil test so only values that are 1 pass; glStencilFuncGL_ EQUAL, 1, 1(GL_ EQUAL, 1, 1).
72.
Draw the second image. Only pixels with stencil value of 1 will change.
73.
Repeat the process, updating the stencil buffer, so that more and more stencil values are 1, using your dissolve pattern, and redrawing image 1 and 2, until the entire stencil buffer has 1's in it, and only image 2 is visible.

If each new frame's dissolve pattern is a superset of the previous frame's pattern, image 1 doesn't have to be re-rendered. This is because once a pixel of image 1 is replaced with image 2, image 1 will never be redrawn there. Designing the dissolve pattern with this restriction can improve the performance of this technique.


next up previous contents
Next: 14.2 Motion Blur Up: 14 Special Effects Previous: 14 Special Effects   Contents
2001-01-10