Upcoming Events
Unite 2010
11/10 - 11/12 @ Montréal, Canada

GDC China
12/5 - 12/7 @ Shanghai, China

Asia Game Show 2010
12/24 - 12/27  

GDC 2011
2/28 - 3/4 @ San Francisco, CA

More events...
Quick Stats
89 people currently visiting GDNet.
2406 articles in the reference section.

Help us fight cancer!
Join SETI Team GDNet!
Link to us Events 4 Gamers
Intel sponsors gamedev.net search:

  Contents

 Preface
 Texture Replaces
 Light

 Tecture Operation
 Unit

 Dark Mapping
 Alpha Operations

 Source code
 Printable version

 


  The Series

 The Basics
 First Steps to
 Animation

 Multitexturing
 Building Worlds
 With X Files


 

The Alpha operations

As Direct3D renders a scene, it can integrate color information from several sources: vertex color, the current material, texture map and the color previously written to the render target. It can blend several of these colors. A factor called alpha, which could be stored in vertices, materials and texture maps, can be used to indicate how blending should be weighted.

An alpha value of 0 means full transparency, an alpha value of 1 means some level of semitransparency.

Modulate Alpha

In 1992 I played Comanche from Novalogic the first time. I wondered about making the night flight feature in some missions. The whole terrain, the clouds and the horizon were green.

They looked like modulating a green ambient light with the textures by alpha.

For this example, I switched from a directional light to a green ambient light. This light is modulated with the texture colour:


#if TM != MODULATEALPHA

// Set up the light
if (m_pDeviceInfo->ddDeviceDesc.dwVertexProcessingCaps
    & D3DVTXPCAPS_DIRECTIONALLIGHTS)
{
  D3DLIGHT7 light;
  D3DUtil_InitLight(light, D3DLIGHT_DIRECTIONAL, 0.0f, -0.4f, 1.0f );
  m_pd3dDevice->SetLight(0, &light );
  m_pd3dDevice->LightEnable(0, TRUE );
  m_pd3dDevice->SetRenderState(D3DRENDERSTATE_LIGHTING, TRUE );
}
#else
// Set the ambient light.
D3DCOLOR d3dclrAmbientLightColor = D3DRGBA(0.0f,1.0f,0.0f,1.0f);
m_pd3dDevice->SetRenderState(D3DRENDERSTATE_AMBIENT, d3dclrAmbientLightColor); 
#endif

To modulate the ambient color with the texture:


#elif TM == MODULATEALPHA
m_pd3dDevice->SetTexture(0, D3DTextr_GetSurface("wall.bmp"));
m_pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
m_pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
m_pd3dDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
  
m_pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
m_pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
m_pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
...

Alpha blending with the Frame Buffer

You can use alpha blending to combine the primitive's color with the color previously stored in that pixel of the frame buffer. That's called blending with the frame buffer. 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.

Direct3D uses the following formula to compute the final color for each pixel in the rendered primitive:

FinalColor = SourcePixelColor * SourceBlendFactor + DestPixelColor * DestBlendFactor

It lets you change the SourceBlendFactor and DestBlendFactor flags to generate the effect you want.

I set the following RenderStates in InitDeviceObjects():


... 
#if TM == BLENDWFRAME
m_pd3dDevice->SetRenderState (D3DRENDERSTATE_ALPHABLENDENABLE, TRUE); 

// Set the source blend state.
m_pd3dDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_SRCCOLOR); 

// Set the destination blend state.
m_pd3dDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCCOLOR);
#endif
...

As a result of the calls in the preceding code fragment, Direct3D performs a linear blend between the source color (the color of the primitive being rendered at the current location) and the destination color (the color at the current location in the frame buffer). This gives an appearance similar to tinted glass. Some of the color of the destination object seems to be transmitted through the source object. The rest of it appears to be absorbed.

Alpha blending requires a fair bit of extra math and memory access, so turning it on and off with ALPHABLENDENABLE is worth the effort.

In the Render() method, there's only a call to set the texture:


...
#elif TM == BLENDWFRAME
m_pd3dDevice->SetTexture(0, D3DTextr_GetSurface("wall.bmp"));
#endif
...

I hope you enjoyed our small trip into the word of the Direct3D 7 IM Framework. If you disliked or liked it, give me a sign at wolf@direct3d.net.