Blending with the Frame Buffer

[Previous] [Next]

Whenever Direct3D renders a primitive, it computes the color for each pixel, deriving the color from the primitive's texture, material, and lighting information. You can use alpha blending to combine the primitive's color with the color previously stored in that pixel of the frame buffer (from other primitives or the clear color, that is, the color the scene is specified to be cleared to when you use the IDirect3DDevice7::Clear method).

Using this form of alpha blending, you can simulate semitransparent objects, combine two images, and add special effects such as force fields, flames, plasma beams, and light mapping. Alpha information can be stored in the polygon's vertex structure or in each texel of a texture map. Direct3D uses the following formula to compute the final color for each pixel in the rendered primitive:

FinalColor = SourcePixelColor · SourceBlendFactor + DestPixelColor · DestBlendFactor

The variables used in this equation are defined as follows:

  • FinalColor The pixel color output to the rendering surface
  • SourcePixelColor The pixel color computed for the current primitive
  • SourceBlendFactor The value used to compute the percentage of the source pixel color that will be applied to create the final color (Valid values are 0.0 through 1.0 inclusive.)
  • DestPixelColor The color of the current pixel in the frame buffer
  • DestBlendFactor The percentage of the frame buffer's current color that will be used to create the final color (Valid values are 0.0 through 1.0 inclusive.)

Direct3D lets you change the SourceBlendFactor and DestBlendFactor flags to generate the effect you want. For example, the final pixel will just be the color of the polygon if you set SourceBlendFactor to D3DBLEND_ONE (1.0, 1.0, 1.0, 1.0) and DestBlendFactor to D3DBLEND_ZERO (0.0, 0.0, 0.0, 0.0). On the other extreme, if you set SourceBlendFactor to D3DBLEND_ZERO and DestBlendFactor to D3DBLEND_ONE, the polygon will be completely transparent and the final pixel will just be the color that was previously in the frame buffer. If you set up the blend factors to use values between these extremes such that the source factor and end factor add up to 1.0, the polygon will be blended into the frame buffer with varying levels of transparency. For most of the interesting transparency effects (like flames and plasma beams), you need to set SourceBlendFactor and DestBlendFactor to settings that use the alpha values of the texture or vertices rather than to simple constant values. By varying the alpha values from frame to frame, you can create a shimmering effect. Also, if FinalColor has a value over 1.0—for example, if SourceBlendFactor and DestBlendFactor are both (1.0, 1.0, 1.0, 1.0)—the color values will get saturated at 1.0 because 1.0 is the highest acceptable value.

Recall from earlier chapters that when you set a color, you're actually setting the red, green, blue, and alpha values. Thus you can use the alpha value of the texels in each texture with the SourceBlendFactor variable to control the resulting transparency.

Direct3D uses a variety of formulas to combine a source color and a destination color into the final color, based on the blending flags you choose. As an example, let's say the following variables define the source and destination values:

(sr, sg, sb, sa) is the information in the source pixel.

(dr, dg, db, da) is the information in the destination pixel.

Let's also say that the source blend flag and the destination blend flag are both set to D3DBLEND_SRCALPHA, which generates blend factors represented as (sa, sa, sa, sa). Given these definitions, this formula will compute the final blended color (fr, fg, fb, fa):

(fr, fg, fb, fa) = (sr · sa + dr · sa, sg · sa + dg · sa, sb · sa + db · sa, sa · sa + da · sa)

Here is a description of each of the possible blend flags. Except where noted, these flags can be applied to either the D3DRENDERSTATE_SRCBLEND state or the D3DRENDERSTATE_DESTBLEND state:

  • D3DBLEND_ZERO The blend factor is (0, 0, 0, 0).
  • D3DBLEND_ONE The blend factor is (1, 1, 1, 1).
  • D3DBLEND_SRCCOLOR The blend factor is (sr, sg, sb, sa).
  • D3DBLEND_INVSRCCOLOR The blend factor is (1 - sr, 1 - sg, 1 - sb, 1 - sa).
  • D3DBLEND_SRCALPHA The blend factor is (sa, sa, sa, sa).
  • D3DBLEND_INVSRCALPHA The blend factor is (1 - sa, 1 - sa, 1 - sa, 1 - sa).
  • D3DBLEND_DESTALPHA The blend factor is (da, da, da, da).
  • D3DBLEND_INVDESTALPHA The blend factor is (1 - da, 1 - da, 1 - da, 1 - da).
  • D3DBLEND_DESTCOLOR The blend factor is (dr, dg, db, da).
  • D3DBLEND_INVDESTCOLOR The blend factor is (1 - dr, 1 - dg, 1 - db, 1 - da).
  • D3DBLEND_SRCALPHASAT The blend factor is (f, f, f, 1), where f = min(sa, 1 - da).
  • D3DBLEND_BOTHSRCALPHA This blend factor is obsolete. You can produce the same effect by setting the source and destination blend factors to D3DBLEND_SRCALPHA and D3DBLEND_INVSRCALPHA in separate calls. This blend mode is supported only for the D3DRENDERSTATE_SRCBLEND render state.
  • D3DBLEND_BOTHINVSRCALPHA The source blend factor is (1 - sa, 1 - sa, 1 - sa, 1 - sa), and the destination blend factor is (sa, sa, sa, sa); the destination blend selection is overridden. This blend mode is supported only for the D3DRENDERSTATE_SRCBLEND render state.

Once you've verified that a target system supports alpha blending, you can pass the D3DRENDERSTATE_ALPHABLENDENABLE enumerated value as the first parameter to IDirect3DDevice7::SetRenderState and TRUE as the second parameter to enable alpha transparency blending. Then you can control the blending factors by using the D3DRENDERSTATE_SRCBLEND and D3DRENDERSTATE_DESTBLEND enumerated values, as follows:

 // // Set up alpha blending. // m_pd3dDevice->SetRenderState( D3DRENDERSTATE_ALPHABLENDENABLE,                               TRUE ); m_pd3dDevice->SetRenderState( D3DRENDERSTATE_SRCBLEND,                               D3DBLEND flag ); m_pd3dDevice->SetRenderState( D3DRENDERSTATE_DESTBLEND,                               D3DBLEND flag ); 

To maximize performance, you should set ALPHABLENDENABLE to FALSE for the primitives you're rendering that don't require alpha blending rather than provide constant alpha values, which produce the same effect—that is, just writing the source pixel into the frame buffer without blending it. Alpha blending requires a fair bit of extra math and memory access, so turning it on and off is worth the effort. You should minimize the need to change render states by grouping the objects that require alpha blending. One way to reduce the number of necessary render state changes is to render all opaque polygons first with alpha blending turned off and then to enable alpha blending and render the alpha polygons second.



Inside Direct3D
Inside Direct3D (Dv-Mps Inside)
ISBN: 0735606137
EAN: 2147483647
Year: 1999
Pages: 131

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net