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

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 16461
\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.

tex2html_nowrap 59.
Clear the stencil buffer with glClearGL_STENCIL_BUFFER_BIT(GL_STENCIL_BUFFER_BIT).
tex2html_nowrap 60.
Disable writing to the color buffer, using glColorMaskGL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE).
tex2html_nowrap 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.

tex2html_nowrap 62.
Turn on stenciling; glEnableGL_STENCIL_TEST(GL_STENCIL_TEST).
tex2html_nowrap 63.
Set stencil function to always fail; glStencilFuncGL_NEVER, 1, 1(GL_NEVER, 1, 1).
tex2html_nowrap 64.
Set stencil op to write 1 on stencil test failure; glStencilOpGL_REPLACE, GL_KEEP, GL_KEEP(GL_REPLACE, GL_KEEP, GL_KEEP).
tex2html_nowrap 65.
Write the dissolve pattern to the stencil buffer by drawing geometry or using glDrawPixels().
tex2html_nowrap 66.
Disable writing to the stencil buffer with glStencilMaskGL_FALSE(GL_FALSE).
tex2html_nowrap 67.
Set stencil function to pass on 0; glStencilFuncGL_EQUAL, 0, 1(GL_EQUAL, 0, 1).
tex2html_nowrap 68.
Enable color buffer for writing with glColorMaskGL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE).
tex2html_nowrap 69.
If you're depth testing, turn depth buffer writes back on with glDepthMask().
tex2html_nowrap 70.
Draw the first image. It will only be written where the stencil buffer values are 0.
tex2html_nowrap 71.
Change the stencil test so only values that are 1 pass; glStencilFuncGL_EQUAL, 1, 1(GL_EQUAL, 1, 1).
tex2html_nowrap 72.
Draw the second image. Only pixels with stencil value of 1 will change.
tex2html_nowrap 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
David Blythe
1999-08-06