📄 chapter07.html
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-2">
<META NAME="GENERATOR" CONTENT="Mozilla/4.07 [en] (Win98; I) [Netscape]">
<META NAME="Author" CONTENT="Goran UnreaL Krajnovic">
<TITLE>Chapter 7 - OpenGL Programming Guide (Addison-Wesley Publishing Company)</TITLE>
</HEAD>
<BODY BGCOLOR="#EFEFEF" LINK="#0000FF" VLINK="#551A8B" ALINK="#FF0000">
<DIV ALIGN=right><IMG SRC="figures/SGI_ID.gif" ALT="Silicon Graphics" NOSAVE HEIGHT=43 WIDTH=151 ALIGN=TEXTTOP></DIV>
<PRE>
<HR></PRE>
<H1>
Chapter 7<BR>
Blending, Antialiasing, and Fog</H1>
<B>Chapter Objectives</B>
<P>After reading this chapter, you'll be able to do the following:
<UL>Blend colors to achieve such effects as making objects appear translucent
<BR>
<P>Smooth jagged edges of lines and polygons with antialiasing
<BR>
<P>Create scenes with realistic atmospheric effects</UL>
The preceding chapters have given you the basic information you need to
create a computer-graphics scene; you've learned how to do the following:
<UL>Draw geometric shapes
<BR>
<P>Transform them so that they can be viewed from whatever perspective
you wish
<BR>
<P>Use display lists to maximize your program's efficiency
<BR>
<P>Specify how the geometric shapes in your scene should be colored and
shaded
<BR>
<P>Add lights and indicate how they should affect the shapes in your scene</UL>
Now you're ready to get a little fancier. This chapter discusses three
techniques that can add extra detail and polish to your scene. None of
these techniques is hard to use - in fact, it's probably harder to explain
them than to use them. Each of these techniques is described in its own
major section:
<UL>"Blending" tells you how to specify a blending function that combines
color values from a source and a destination. The final effect is that
parts of your scene appear translucent.
<BR>
<P>"Antialiasing" explains this relatively subtle technique that alters
colors so that the edges of points, lines, and polygons appear smooth rather
than angular and jagged.
<BR>
<P>"Fog" describes how to create the illusion of depth by computing the
color values of an object based on distance from the viewpoint. Thus, objects
that are far away appear to fade into the background, just as they do in
real life.</UL>
<HR>
<H2>
<A NAME="X"></A>Blending</H2>
You've already seen alpha values (alpha is the A in RGBA), but they've
always been 1.0, and they haven't been discussed. Alpha values are specified
with <B>glColor*()</B>, when using <B>glClearColor()</B> to specify a clearing
color, and when specifying certain lighting parameters such as a material
property or light-source intensity. As you learned in Chapter 5 , the pixels
on a monitor screen emit red, green, and blue light, which is controlled
by the red, green, and blue color values. So how does an alpha value affect
what gets drawn in a window on the screen? When blending is enabled, the
alpha value is used to combine the color value of the fragment being processed
with that of the pixel already stored in the framebuffer. Blending occurs
after your scene has been rasterized and converted to fragments, but just
before the final pixels are drawn in the framebuffer. Alpha values can
also be used in the alpha test to accept or reject a fragment based on
its alpha value. See Chapter 10 for more information about this process.
<P>Without blending, each new fragment overwrites any existing color values
in the framebuffer, as though the fragment is opaque. With blending, you
can control how much of the existing color value should be combined with
the new fragment's value. Thus, you can use alpha blending to create a
translucent fragment, one that lets some of the previously stored color
value "show through." Color blending lies at the heart of techniques such
as transparency, digital compositing, and painting.
<P>Alpha values aren't specified in color-index mode. Thus, blending operations
aren't performed in color-index mode
<P>The most natural way for you to think of blending operations is to view
the RGB components of a fragment as representing its color, and the alpha
component as representing opacity. Thus, transparent or translucent surfaces
have lower opacity than opaque ones. For example, if you're viewing an
object through green glass, the color you see is partly green from the
glass and partly the color of the object. The percentage varies depending
on the transmission properties of the glass: If the glass transmits 80
percent of the light that strikes it (that is, has an opacity of 20 percent),
the color you see is a combination of 20 percent glass color and 80 percent
of the color of the object behind it. You can easily imagine situations
with multiple translucent surfaces. If you look at an automobile, for instance,
its interior has one piece of glass between it and your viewpoint; some
objects behind the automobile are visible through two pieces of glass.
<H3>
The Source and Destination Factors</H3>
During blending, color values of the incoming fragment (the <I>source</I>)
are combined with the color values of the corresponding currently stored
pixel (the <I>destination</I>) in a two-stage process. First, you specify
how to compute source and destination factors. These factors are RGBA quadruplets
that are multiplied by each component of the R, G, B, and A values in the
source and destination, respectively. Then, the corresponding components
in the two sets of RGBA quadruplets are added. To show this mathematically,
let the source and destination blending factors be (Sr, Sg, Sb, Sa) and
(Dr, Dg, Db, Da), respectively, and the RGBA values of the source and destination
be indicated with a subscript of s or d. Then, the final, blended RGBA
values are given by
<P>(RsSr+RdDr, GsSg+GdDg, BsSb+BdDb, AsSa+AdDa)
<P>Each component of this quadruplet is eventually clamped to [0,1].
<P>Now let's look at how the source and destination blending factors are
generated. You use <B>glBlendFunc()</B> to supply two constants: one that
specifies how the source factor should be computed, and one that indicates
how the destination factor should be computed. Also, to have blending take
effect, you need to enable it:
<PRE>glEnable(GL_BLEND);</PRE>
Use <B>glDisable()</B> with GL_BLEND to disable blending. Also, note that
using the constants GL_ONE (source) and GL_ZERO (destination) gives the
same results as when blending is disabled; these values are the default.void
<B>glBlendFunc</B>(GLenum <I>sfactor</I>, GLenum <I>dfactor</I>)
<P>Controls how color values in the fragment being processed (the source)
are combined with those already stored in the framebuffer (the destination).
The argument <I>sfactor</I> indicates how to compute a source blending
factor; <I>dfactor</I> indicates how to compute a destination blending
factor. The possible values for these arguments are explained in Table
7-1 . The blend factors are assumed to lie in the range [0,1]; after the
color values in the source and destination are combined, they're clamped
to the range [0,1].
<P>In Table 7-1 , the RGBA values of the source and destination are indicated
with the subscripts s and d, respectively. Also, division of an RGBA quadruplet
by a scalar means dividing each component by that value. Similarly, subtraction
of quadruplets means subtracting them componentwise. The Relevant Factor
column indicates whether the corresponding constant can be used to specify
the source or destination blend factor.
<TABLE BORDER CELLPADDING=10 >
<CAPTION ALIGN=TOP><B>Table 7-1 : </B>Source and Destination Blending Factors</CAPTION>
<TR ALIGN=LEFT VALIGN=TOP>
<TH>Constant</TH>
<TH>Relevant Factor</TH>
<TH>Computed Blend Factor</TH>
</TR>
<TR ALIGN=LEFT VALIGN=TOP>
<TD>GL_ZERO</TD>
<TD>source or destination</TD>
<TD>(0, 0, 0, 0)</TD>
</TR>
<TR ALIGN=LEFT VALIGN=TOP>
<TD>GL_ONE</TD>
<TD>source or destination</TD>
<TD>(1, 1, 1, 1)</TD>
</TR>
<TR ALIGN=LEFT VALIGN=TOP>
<TD>GL_DST_COLOR</TD>
<TD>source</TD>
<TD>(Rd, Gd, Bd, Ad)</TD>
</TR>
<TR ALIGN=LEFT VALIGN=TOP>
<TD>GL_SRC_COLOR</TD>
<TD>destination</TD>
<TD>(Rs, Gs, Bs, As)</TD>
</TR>
<TR ALIGN=LEFT VALIGN=TOP>
<TD>GL_ONE_MINUS_DST_COLOR</TD>
<TD>source</TD>
<TD>(1, 1, 1, 1)-(Rd, Gd, Bd, Ad)</TD>
</TR>
<TR ALIGN=LEFT VALIGN=TOP>
<TD>GL_ONE_MINUS_SRC_COLOR</TD>
<TD>destination</TD>
<TD>(1, 1, 1, 1)-(Rs, Gs, Bs, As)</TD>
</TR>
<TR ALIGN=LEFT VALIGN=TOP>
<TD>GL_SRC_ALPHA</TD>
<TD>source or destination</TD>
<TD>(As, As, As, As)</TD>
</TR>
<TR ALIGN=LEFT VALIGN=TOP>
<TD>GL_ONE_MINUS_SRC_ALPH A</TD>
<TD>source or destination</TD>
<TD>(1, 1, 1, 1)-(As, As, As, As)</TD>
</TR>
<TR ALIGN=LEFT VALIGN=TOP>
<TD>GL_DST_ALPHA</TD>
<TD>source or destination</TD>
<TD>(Ad, Ad, Ad, Ad)</TD>
</TR>
<TR ALIGN=LEFT VALIGN=TOP>
<TD>GL_ONE_MINUS_DST_ALPH A</TD>
<TD>source or destination</TD>
<TD>(1, 1, 1, 1)-(Ad, Ad, Ad, Ad)</TD>
</TR>
<TR ALIGN=LEFT VALIGN=TOP>
<TD>GL_SRC_ALPHA_SATURATE</TD>
<TD>source</TD>
<TD>(f, f, f, 1); f=min(As, 1-Ad)</TD>
</TR>
</TABLE>
<BR>
<H3>
Sample Uses of Blending</H3>
Not all of the combinations of source and destination factors make sense.
The majority of applications use a small number of combinations. The following
paragraphs describe typical uses for particular combinations of the source
and destination factors. Some of these examples use only the incoming alpha
value, so they work even when alpha values aren't stored in the framebuffer.
Also, note that often there's more than one way to achieve some of these
effects.
<OL>One way to draw a picture composed half of one image and half of another,
equally blended, is to set the source factor to GL_ONE, draw the first
image, then set the source and destination factors to GL_SRC_ALPHA, and
draw the second image with alpha equal to 0.5. If the picture is supposed
to be blended with 0.75 of the first image and 0.25 of the second, draw
the first image as before, and draw the second with an alpha of 0.25, but
with GL_SRC_ALPHA (source) and GL_ONE_MINUS_SRC_ALPHA (destination). This
pair of factors probably represents the most commonly used blending operation.
<BR>
<P>To blend three different images equally, set the destination factor
to GL_ONE and the source factor to GL_SRC_ALPHA. Draw each of the images
with an alpha equal to 0.3333333. With this technique, each image is only
one-third of its original brightness, which is noticeable where the images
don't overlap.
<BR>
<P>Suppose you're writing a paint program, and you want to have a brush
that gradually adds color so that each brush stroke blends in a little
more color with whatever is currently in the image (say 10 percent color
with 90 percent image on each pass). To do this, draw the image of the
brush with alpha of 10 percent and use GL_SRC_ALPHA (source) and GL_ONE_MINUS_SRC_ALPHA
(destination). (Note that you can vary the alphas across the brush to make
the brush add more of its color in the middle and less on the edges, for
an antialiased brush shape. See "Antialiasing." ) Similarly, erasers can
be implemented by setting the eraser color to the background color.
<BR>
<P>The blending functions that use the source or destination colors - GL_DST_COLOR
or GL_ONE_MINUS_DST_COLOR for the source factor and GL_SRC_COLOR or GL_ONE_MINUS_SRC_COLOR
for the destination factor - effectively allow you to modulate each color
component individually. This operation is equivalent to applying a simple
filter - for example, multiplying the red component by 80 percent, the
green component by 40 percent, and the blue component by 72 percent would
simulate viewing the scene through a photographic filter that blocks 20
percent of red light, 60 percent of green, and 28 percent of blue.
<BR>
<P>Suppose you want to draw a picture composed of three translucent surfaces,
some obscuring others and all over a solid background. Assume the farthest
surface transmits 80 percent of the color behind it, the next transmits
40 percent, and the closest transmits 90 percent. To compose this picture,
draw the background first with the default source and destination factors,
and then change the blending factors to GL_SRC_ALPHA (source) and GL_ONE_MINUS_SRC_ALPHA
(destination). Next, draw the farthest surface with an alpha of 0.2, then
the middle surface with an alpha of 0.6, and finally the closest surface
with an alpha of 0.1.
<P><B>Advanced</B>
<BR>
<P>If your system has alpha planes, you can render objects one at a time
(including their alpha values), read them back, and then perform interesting
matting or compositing operations with the fully rendered objects. See
"Compositing 3D Rendered Images" by Tom Duff, SIGGRAPH 1985 Proceedings,
p. 41-44, for examples of this technique. Note that objects used for picture
composition can come from any source - they can be rendered using OpenGL
commands, rendered using techniques such as ray-tracing or radiosity that
are implemented in another graphics library, or obtained by scanning in
existing images.
<P><B>Advanced</B>
<BR>
<P>You can create the effect of a nonrectangular raster image by assigning
different alpha values to individual fragments in the image. Assign an
alpha of 0 to each "invisible" fragment, and an alpha of 1.0 to each opaque
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -