| Texture 
  BlendingAuthor 
  : 
  Jack Hoxley
 Written : 28th April 2001
 Contact : [Web] 
  [Email]
 Download : Graph_12.Zip
[128 Kb]
 
 Contents 
  of this lesson:1.  Introduction
 2.  Multi-Pass Blending
 3.  Proper Texture Blending
 4.  Vertex Based Alpha Blending
 5.  Material Based Alpha Blending
 6.  Texture Based Alpha Blending
 
 1. 
  Introduction Welcome to Advanced Texturing part 1, this section of the DirectXGraphics 
  series will cover some of the cleverer features that we can use in DirectX8. 
  First up is texture blending, a very simple, quite fast and excellent tool to 
  be able to use. Texture blending is the process of taking up to 8 textures and 
  combining them based on several arguments and parameters. Several extremely 
  cool effects can be derived from this capability, the main one being the usage 
  of lightmaps. Currently you should be aware that Direct3D does it's lighting 
  on a per-vertex basis - then blends the results across the rest of the triangle. 
  90% of the time this is perfectly acceptable, but there are times when visible 
  artifacts appear - and it looks very wrong. For example, take a spot light and 
  a large polygon; as you know, if the vertex isn't within the cone it receives 
  no light, when we have a small cone and a large triangle it is perfectly possible 
  to have the light move to the middle of the triangle and the triangle to
receive 
  no light at all; when in real life it should leave a small circle of colour. 
  The inverse can happen as well, if we have a small spotlight move over one corner 
  of our large triangle it can appear to be a very big spotlight - because of 
  the linear interpolation across the triangle. To solve this you could use lightmaps, 
  whilst not always as real-time as you'd like (but they are perfect if you pre-compile 
  the world data) you can get pixel-perfect lighting as a result. And as you're 
  using textures you can define whole new types of lighting - one that gets brighter 
  towards the edge, one that doesn't go in straight lines...  This article will introduce you to the two main types of texture 
  blending, there is a third (new to DirectX8) in the form of pixel shaders, but 
  they are extremely complicated - and involve a simplified version of assembler 
  code.  
 2. 
  Multi-Pass Blending Multi-pass texture blending is the easiest way possible, unfortunately 
  it's also the slowest method as well. By setting the source and destination 
  render states you can render a piece of geometry with a texture and then render 
  it again with a different texture and Direct3D will blend it accordingly. BUT 
  as I just hinted at, you need to render the geometry twice - which isn't very 
  frame-rate friendly. If you have a character with 1000 vertices, to blend two 
  textures across the whole model you'd need to render 2000 vertices in total 
  - which can destroy your frame rate if you're not careful. In order to do multi-pass texture blending you need to set these 
  three render states: 
                                          
                                          
                                            
                                              
                                                | 
                                                    
                                                      
                                                        | 
                                                            
                                                              
                                                                | 
                                                                    
                                                                      
                                                                        | D3DDevice.SetRenderState
                                                                          D3DRS_SRCBLEND,
                                                                          D3DBLEND_SRCCOLOR D3DDevice.SetRenderState
                                                                          D3DRS_DESTBLEND,
                                                                          D3DBLEND_DESTCOLOR
 D3DDevice.SetRenderState
                                                                          D3DRS_ALPHABLENDENABLE,
                                                                          1
 |  |  |  |  Just remember to disable blending for any geometry that you dont 
  want blended. The last parameter, specifying what sort of blend you want are 
  described in the next table: 
  
    The best way of learning how these work is to play around with them, using D3DBLEND_ONE 
  for both parameters creates a 
      | D3DBLEND_ONE | The 
        layer will be blended as (1,1,1,1) - white, everything appears much brighter. |   
      | D3DBLEND_ZERO | The 
        layer will be blended as (0,0,0,0) - black. |   
      | D3DBLEND_SRCCOLOR | Uses 
        the colour components of the source image |   
      | D3DBLEND_INVSRCCOLOR | Invertex 
        the colour components of the source image, 1-sR, 1-sG, 1-sB, 1-sA |   
      | D3DBLEND_SRCALPHA | Uses 
        the source alpha component on all channels, (A, A, A, A) |   
      | D3DBLEND_INVSRCALPHA | Inverts 
        the source alpha, 1 - A them same as SRCALPHA |   
      | D3DBLEND_DESTALPHA | Uses 
        the destination alpha component on all channels, as in SRCALPHA |   
      | D3DBLEND_INVDESTALPHA | Inverts 
        the destination alpha then does the same as DESTALPHA |   
      | D3DBLEND_DESTCOLOR | Uses 
        the destination colour components |   
      | D3DBLEND_INVDESTCOLOR | Inverts 
        the destination colour components |   
      | D3DBLEND_SRCALPHASAT | Blend 
        factor is (F, F, F, 1) where F = Min(srcA, 1 - destA) |   
      | D3DBLEND_BOTHSRCALPHA | Not 
        supported in DirectX8, do not use |   
      | D3DBLEND_BOTHINVSRCALPHA | Inverts 
        the source alpha, then uses the original alpha on the destination; any 
        destination blend parameters are ignored. |  semi alpha-blending type effect, using D3DBLEND_SRCCOLOR and D3DBLEND_DESTCOLOR 
  in the source and dest
 entries allows you to use lightmaps, like the picture below:
 An example of Multi-pass texture blending when used for lightmapping. 
  The first texture is what we wantdisplayed on the primative, the second texture is our lightmap - white areas 
  are bright, black areas have
 no light. When blended together we get the result in the third box.
 To render using multi-pass blending all you need to do is switch 
  on the blending when it's required - then re-render the geometry. This following 
  piece of code is from the Render( ) procedure in the sample code: 
                                          
                                          
                                            
                                              
                                                | 
                                                    
                                                      
                                                        | 
                                                            
                                                              
                                                                | 
                                                                    
                                                                      
                                                                        | D3DDevice.SetTexture
                                                                          0,
                                                                          LightMapTex D3DDevice.DrawPrimitiveUP
                                                                          D3DPT_TRIANGLESTRIP,
                                                                          2,
                                                                          TriStrip3(0),
                                                                          Len(TriStrip3(0))
 
 D3DDevice.SetTexture 0, Texture
 D3DDevice.SetRenderState
                                                                          D3DRS_ALPHABLENDENABLE,
                                                                          1
 D3DDevice.DrawPrimitiveUP
                                                                          D3DPT_TRIANGLESTRIP,
                                                                          2,
                                                                          TriStrip3(0),
                                                                          Len(TriStrip3(0))
 D3DDevice.SetRenderState
                                                                          D3DRS_ALPHABLENDENABLE,
                                                                          0
 |  |  |  |  Notice that the first stage does not have blending enabled, when 
  you use blending it blends with whatever pixel colours are already there, so 
  in this case it would blend with the black background before blending with the 
  second layer. Make sure that you turn blending off after you have finished, 
  you may well end up getting other geometry blended by mistake - on top of that 
  blending is much slower than not blending, so the less you use it the faster 
  your game will go. 
 3. 
  Proper Texture Blending Proper texture blending is where all textures are blended in one 
  pass, you only need to render the geometry once. It also has it's side effects, 
  You have to query if there is hardware support for more than one texture, The 
  newer and more powerful accelerator cards can handle 8 at a time, older cards 
  only support 1 or 2. The first step then is to decide what support there is for 
  multiple texture stages: 
                                          
                                          
                                            
                                              
                                                | 
                                                    
                                                      
                                                        | 
                                                            
                                                              
                                                                | 
                                                                    
                                                                      
                                                                        | Dim
                                                                          CAPS
                                                                          As
                                                                          D3DCAPS8 D3DDevice.GetDeviceCaps
                                                                          CAPS
 Debug.Print
                                                                          "Maximum
                                                                          Texture
                                                                          Stages:
                                                                          "
                                                                          &
                                                                          CAPS.MaxTextureBlendStages
 |  |  |  |  Simple as that really, we'd want to store it as a variable rather 
  than just output it to the immediate window - but you get the idea. Now that 
  we know how many (there will be at least one) we can start playing. You'll have 
  seen the line "D3DDevice.SetTexture 0, TextureName" many times already 
  in this series, the first parameter, 0 in this case, is the texture stage; if 
  there is one texture stage we can only place a texture in entry 0 (any higher 
  and it'll drop out), if we support 8 texture stages we can put textures in slots 
  0 to 7... Bare in mind that the more you fill up the slower it goes. Now that we know if the current device supports multiple texture
stages (and how many) we can start to do something with them. This looks quite
complicated at first, but once you start to get your head around the hierarchy
(more on that later) then it becomes quite simple. Here's the multiple-stage
texture blending code from the sample code: 
                                          
                                          
                                            
                                              
                                                | 
                                                    
                                                      
                                                        | 
                                                            
                                                              
                                                                | 
                                                                    
                                                                      
                                                                        | If CanDoBlending = True Then
        D3DDevice.SetVertexShader FVF2
        D3DDevice.SetTexture 0, LightMapTexCol
        Call D3DDevice.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE)
        Call D3DDevice.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE)
        Call D3DDevice.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE)
        D3DDevice.SetTexture 1, Texture
        Call D3DDevice.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MODULATE)
        Call D3DDevice.SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE)
        Call D3DDevice.SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT)
        D3DDevice.DrawPrimitiveUP D3DPT_TRIANGLESTRIP, 2, TriStrip4(0), Len(TriStrip4(0))
End If |  |  |  |  
                                        
                                        The above code is executed in the
                                        Render() function, whilst it sets up the
                                        texture stages each frame it's not
                                        required to (we could just configure
                                        them during initialisation). When
                                        executed, the above code will perform
                                        standard colour lightmaping, using the
                                        first stage (0) as the lightmap (which
                                        areas are light/dark) and the second
                                        stage (1) as the actual texture. The
                                        final result is shown below:
                                         
                                        The main texture is the same as before,
                                        but the lightmap is
 now a magenta-cyan radial gradient.
 
                                        
                                        One final important thing to note is
                                        that we have to use two sets of texture
                                        coordinates now, this also requires that
                                        we create a new vertex format to obtain
                                        this functionality. This is quite
                                        simply:
                                         
                                          
                                          
                                            
                                              
                                                | 
                                                    
                                                      
                                                        | 
                                                            
                                                              
                                                                | 
                                                                    
                                                                      
                                                                        | Private Type TLVERTEX2
    X As Single
    Y As Single
    Z As Single
    rhw As Single
    color As Long
    specular As Long
    tu1 As Single
    tv1 As Single
    tu2 As Single
    tv2 As Single
End Type
Const FVF2 = D3DFVF_XYZRHW Or D3DFVF_DIFFUSE Or D3DFVF_SPECULAR Or D3DFVF_TEX2 |  |  |  |  The actual member names for the coordinates (tu1 or tu2) is not important,
they need to be in the correct order and of the correct size, but you could call
one "mushroom" and the other "fred", but it's unlikely to
help you later on! You could also specify them using other built in types,
namely the D3DVECTOR* types (see next example). Finally, note that the FVF
constant has D3DFVF_TEX2 instead of _TEX1, fairly logical this one, it just
means that we're passing two texture coordinates - you can use _TEX1 - TEX8
here, depending on how many blending stages you require. A revised definition of
this vertex format could be:
                                         
                                          
                                          
                                            
                                              
                                                | 
                                                    
                                                      
                                                        | 
                                                            
                                                              
                                                                | 
                                                                    
                                                                      
                                                                        | Private Type TLVERTEX3
    P As D3DVECTOR4
    Color As Long
    Specular As Long
    Tex0 As D3DVECTOR2
    Tex1 As D3DVECTOR2
    Tex2 As D3DVECTOR2
End Type
Const FVF3 = D3DFVF_XYZRHW Or D3DFVF_DIFFUSE Or D3DFVF_SPECULAR Or D3DFVF_TEX3 |  |  |  |  
                                        
                                        When you're creating the vertices do so
                                        as per usual, but specify the texture
                                        coordinates with respect to their
                                        texture stage - should you only want 1/2
                                        of the lightmap to light the entire of
                                        the texture you can set Tex0
                                        =[0,0]-[0.5,0.5] and Tex1=[0,0]-[1,1]...
                                         Now that we know how to set up the texture stages, we need a little
background theory. How does the texture cascade work? what parameters do what?
Take the following diagram:
                                         
                                         Think of each stage as a logic gate (if you've done electronics
before), or a little number generator (like in first school/little-person
school). In goes two numbers (Arg1, Arg2) and out comes a new number, what
happens in the box is the blending operation. The diagram above shows the
process for 4 texture stages, but you can see how it goes onto use all 8 stages
(if required). Direct3D supports dozens of different texture stage operations,
you should enumerate for their availability (see the object browser in VB for
specific flags) before using them, but most of the simple/common blending
functions are supported by most hardware your program will encounter. The
specific operations are listed in the help file, but the most common (and most
useful) are listed below:
                                         D3DTSS_COLOROP - The colour
blending operationD3DTSS_COLORARG0 - The first input argument, not usually used - but required for
some functions (lerping for example)
 D3DTSS_COLORARG1 - The second colour based argument, what is specified here is
used as the first parameter for most operations
 D3DTSS_COLORARG2 - The third colour based argument.
 D3DTSS_ALPHAOP - The alpha
blending operation, same as the colour blending, but only operates on the alpha
channelD3DTSS_ALPHAARG0 - The first input, as with colours, this is only used in
special cases.
 D3DTSS_ALPHAARG1 - The second input, used in most calculations
 D3DTSS_ALPHAARG2 - The third input.
 D3DTSS_MAGFILTER - The
magnification filter for the texture stage, point, bilinear or anisotropic
usually.D3DTSS_MINFILTER - The minification filter for the current texture stage, same
parameters as for magnification.
 Above are the main parameters, we
now need to specify what the inputs are and how to specify the operation. First
up, the operations: D3DTOP_DISABLE - Disables the
current stage, and all those after it. If stage 4 was disabled, 4,5,6,7,8 would
not be processed.D3DTOP_SELECTARG1 - the output is the input in argument 1, unaltered. argument 2
is ignored.
 D3DTOP_SELECTARG2 - the same as above, but the output is argument 2
 D3DTOP_MODULATE - multiplies the ARG1 and ARG2 values.
 D3DTOP_MODULATE2X - Same as modulate, but the final value is multiplied by 2,
slightly brightening the image
 D3DTOP_MODULATE4X - Same as above, but the final value is multiplied by 4,
brightening the final result even more
 D3DTOP_LERP - linear interpolation using the ARG1 and ARG2 values by a given
value in ARG0 (0.0 to 1.0 based)
 D3DTOP_MULTIPLYADD - Adds ARG0 and ARG1 and multiplies by ARG2
 These values should be paired with
the _COLOROP, _ALPHAOP and similar parameters, setting this values with the ARG*
parameters will result in undefined behaviour. Now that we have a few operations
to play with we need to know how to specify values for the arguments. Again, a
short list of the most useful and most common argument parameters: D3DTA_CURRENT - this uses the
result from the last operation in the current, in the first stage (0) this is
taken as being D3DTA_DIFFUSED3DTA_DIFFUSE - This is the current texels colour after lighting (if used) and
gouraud shading.
 D3DTA_SPECULAR - similiar to the _DIFFUSE argument, but specifies the
interpolated specular value
 D3DTA_TEXTURE - the colour for the pixel in the stages texture, if no texture is
specified [1,1,1,1] (white) is returned.
 
 Done. We now have all the
information required, except one thing - the interface call to specify these
values. This is one that you've already seen: 
                                          
                                          
                                            
                                              
                                                | 
                                                    
                                                      
                                                        | 
                                                            
                                                              
                                                                | 
                                                                    
                                                                      
                                                                        | SetTextureStageState(Stage
                                                                          As
                                                                          Long,
                                                                          _ Type
                                                                          As
                                                                          CONST_D3DTEXTURESTAGESTATETYPE,
                                                                          _
 Value
                                                                          As
                                                                          Long)
 |  |  |  |  Any of the D3DTSS_ constants go in the second
parameter (such as D3DTSS_COLOROP), followed by an appropriate value for the
second parameter, if the second parameter is one of the operations specifiers (_COLOROP
or _ALPHAOP) then the third parameter needs to be a D3DTOP_ constant. If the
second parameter is an ARG* (D3DTSS_COLORARG1 for example) then you need to
specify one of the D3DTA_ constants in the third parameter. Obviously the first
parameter is the stage that you're currently altering. A brief list of examples
for texture blending would be:
                                         Color Light Mapping
                                         
                                          
                                          
                                            
                                              
                                                | 
                                                    
                                                      
                                                        | 
                                                            
                                                              
                                                                | 
                                                                    
                                                                      
                                                                        | D3DDevice.SetTexture 0, LightMapTexture
        Call D3DDevice.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE)
        Call D3DDevice.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_TEXTURE)
        Call D3DDevice.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_DIFFUSE)
        D3DDevice.SetTexture 1, Texture
        Call D3DDevice.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MODULATE)
        Call D3DDevice.SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_TEXTURE)
        Call D3DDevice.SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_CURRENT) |  |  |  |  Monochrome Light Mapping
                                         
                                          
                                          
                                            
                                              
                                                | 
                                                    
                                                      
                                                        | 
                                                            
                                                              
                                                                | 
                                                                    
                                                                      
                                                                        | 'This example assumes the lighting data is in greyscale form in the textures alpha channel.
' Set the light map texture as the current texture.
Call D3DDevice.SetTexture(0, texLightMap)
' Set the color operation.
Call D3DDevice.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1)
' Set argument 1 to the color operation.
Call D3DDevice.SetTextureStageState(0, D3DTSS_COLORARG1, _
                            D3DTA_TEXTURE Or D3DTA_ALPHAREPLICATE) |  |  |  |  Specular Light Mapping
                                         
                                          
                                          
                                            
                                              
                                                | 
                                                    
                                                      
                                                        | 
                                                            
                                                              
                                                                | 
                                                                    
                                                                      
                                                                        | ' Set the base texture.
Call D3DDevice.SetTexture(0, texBaseTexture)
' Set the base texture operation and args.
Call D3DDevice.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE)
Call D3DDevice.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE)
Call D3DDevice.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE)
' Set the specular light map.
Call D3DDevice.SetTexture(1, texSpecLightMap)
' Set the specular light map operation and args.
Call D3DDevice.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_ADD)
Call D3DDevice.SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE)
Call D3DDevice.SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT)
' Set the RGB light map.
Call D3DDevice.SetTexture(2, texLightMap)
' Set the RGB light map operation and args
Call D3DDevice.SetTextureStageState(2, D3DTSS_COLOROP, D3DTOP_MODULATE)
Call D3DDevice.SetTextureStageState(2, D3DTSS_COLORARG1, D3DTA_TEXTURE)
Call D3DDevice.SetTextureStageState(2, D3DTSS_COLORARG2, D3DTA_CURRENT) |  |  |  |    
 4.
Vertex Based Alpha Blending Alpha blending, what is it? why
does everyone love it so much? Alpha blending is the process of blending a
source colour and a destination colour based on an alpha value, this alpha value
can either be specified externally, or be part of the actual pixel colour -
currently you've probably only seen RGB notation, now we use ARGB or RGBA; where
the A value is our alpha value. Changing this alpha value we can achieve
translucency effects with geometry and textures - enabling you to replicate
glass, water, smoke and any number of special effects. Traditionally the process
of alpha blending has been far too slow to be done in real-time, the
calculations required are very simple, but multiply it by the number of pixels
that need to be blended and you'll very quickly see why it's slow. Direct3D
allows us to use the hardware to do the blending, therefore making alpha
blending an almost effortless process (don't overkill on it though). The fastest method of using alpha
blending is to do it on a per-vertex basis and let Direct3D interpolate the
values across a triangle. This isn't incredibly accurate, and only works for
vertices that you manually light yourself. To embed an alpha value in the vertex
colour we simply change the current RRGGBB hex value to be an AARRGGBB hex value
- simple as that. For example: 
                                          
                                          
                                            
                                              
                                                | 
                                                    
                                                      
                                                        | 
                                                            
                                                              
                                                                | 
                                                                    
                                                                      
                                                                        | 'vertex 0 TriStrip(0) = CreateTLVertex(10, 10, 0, 1, &H80FFFFFF, 0, 0, 0)
 
 'vertex 1
 TriStrip(1) = CreateTLVertex(210, 10, 0, 1, &H80FFFFFF, 0, 1, 0)
 
 'vertex 2
 TriStrip(2) = CreateTLVertex(10, 210, 0, 1, &H80FFFFFF, 0, 0, 1)
 
 'vertex 3
 TriStrip(3) = CreateTLVertex(210, 210, 0, 1, &H80FFFFFF, 0, 1, 1)
 |  |  |  |  
                                        
                                        notice that the first part of the hex
                                        value is '80' - in decimal notation
                                        that's 128, or 0.5 alpha - indicating
                                        that we blend this vertex's colour 50:50
                                        with whatever is behind it, if we
                                        changed the hex value to be EE (238 in
                                        decimal) we would get an almost opaque
                                        result - you may just see a bit of the
                                        background appearing through the
                                        triangle, alternatively change the value
                                        to be 19 (50 in decimal) and you'd get
                                        an almost transparent result - you'd
                                        only just see the geometry over the
                                        background. As mentioned, the alpha
                                        operation blends the current stage with
                                        whatever is behind it, therefore, when
                                        rendering, make sure everything that is
                                        behind the geometry has been rendered
                                        before rendering a semi-transparent
                                        object - unwanted artifacts will result
                                        otherwise.
                                         
                                        
                                        To enable vertex based alpha blending
                                        you need to use the texture cascade (see
                                        previous section), however it's not
                                        dependant on having multiple stages
                                        available - we're only going to be
                                        changing the first one. Here is the code
                                        required to setup per-vertex alpha
                                        blending:
                                         
                                          
                                          
                                            
                                              
                                                | 
                                                    
                                                      
                                                        | 
                                                            
                                                              
                                                                | 
                                                                    
                                                                      
                                                                        | Call D3DDevice.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE) Call D3DDevice.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE)
 Call D3DDevice.SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_CURRENT)
 |  |  |  |  
                                        
                                        If you apply your knowledge from section
                                        3 you'll understand how this works, we
                                        tell it to modulate the alpha values
                                        based on the diffuse colour (in both
                                        arguments), because it's an alpha blend
                                        it will automatically use whatever value
                                        is behind it. If this is the only form
                                        of texture blending being used then you
                                        can omit the ARG* lines and just specify
                                        the ALPHAOP, but if there are other
                                        parameters being used you may wish to
                                        make sure that the correct arguments are
                                        still in place.
                                         
 5.
Material Based Alpha Blending This
is a nice simple one this, but useful to know about. The first (per-vertex)
technique only work with manually lit vertices - where you can specify the
colour. So what happens when you're letting Direct3D do the lighting for you?
You use the material properties! You have no where near the same amount of
control (no interpolation across a triangle), but it's useful for making an
entire model/buffer a certain colour or opacity (the alpha value is measured as
opacity - best seen in paint packages), it's also excellent for motion blur
(should you like that sort of thing). Here's how we configure our material,
apply it to the device, and then make sure Direct3D uses the alpha component: 
                                          
                                          
                                            
                                              
                                                | 
                                                    
                                                      
                                                        | 
                                                            
                                                              
                                                                | 
                                                                    
                                                                      
                                                                        | D3DDevice.SetRenderState D3DRS_ALPHABLENDENABLE, 1 D3DDevice.SetRenderState D3DRS_DESTBLEND, D3DBLEND_SRCCOLOR
 D3DDevice.SetRenderState D3DRS_SRCBLEND, D3DBLEND_SRCALPHA
 Dim
                                                                          mat as
                                                                          D3DMATERIAL8mat.Col.A=AlphaVal
                                                                          'on a
                                                                          0.0 to
                                                                          1.0
                                                                          scale
 mat.Col.R
                                                                          = 1:
                                                                          mat.Col.G
                                                                          = 1:
                                                                          mat.Col.B
                                                                          = 1
                                                                          'material
                                                                          color
                                                                          doesn't
                                                                          affect
                                                                          texture
                                                                          or
                                                                          lighting
                                                                          colour
 mat.Ambient
                                                                          =
                                                                          mat.Col
 mat.Diffuse
                                                                          =
                                                                          mat.Col
 D3DDevice.SetMaterial
                                                                          mat '//Render
                                                                          geometry
                                                                          here! D3DDevice.SetRenderState D3DRS_ALPHABLENDENABLE,
                                                                          0 |  |  |  |  
                                        
                                        Not too complicated really, just make
                                        sure that you disable alpha blending
                                        after you're finished (otherwise other
                                        objects will get alpha-blended as well).
                                         
 6.
Texture Based Alpha Blending Now
we're cooking! This is the best type of alpha blending available to you,
consequently it's not the fastest either. As we mentioned for per-vertex based
alpha blending, each vertex uses the ARGB component, so what if we could
specify a texture that had an A component for every pixel in it - we
would get amazing amounts of control over the rendering. Should you want, you
could draw your name in alpha values and have it rendered so that only your name
was semi-transparent over everything. You could also use the alpha-channel to
create a softening/anti-aliasing type effect around the edges of text/geometry -
the possibilities are endless (well, probably a few 1000 possibilities!). The
first stage to this effect is to make a texture that contains an alpha channel;
if you have the DirectX8 SDK then you can use the DXTex tool to combine multiple
files (one as the RGB image, the other as the Alpha channel) - you can use some
paint packages to the same effect, buy you'll have to experiment or read the
help files. The texture supplied with the example code was made using the DXTex
tool, so has an extension of dds. The
code to render geometry using the alpha-channel in the texture looks like this,
note that we have to tell Direct3D we want to use the alpha channel. 
                                          
                                          
                                            
                                              
                                                | 
                                                    
                                                      
                                                        | 
                                                            
                                                              
                                                                | 
                                                                    
                                                                      
                                                                        | D3DDevice.SetVertexShader FVF
D3DDevice.SetTexture 0, TexWithA
D3DDevice.SetRenderState D3DRS_SRCBLEND, D3DBLEND_SRCALPHA
D3DDevice.SetRenderState D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA
D3DDevice.SetRenderState D3DRS_ALPHABLENDENABLE, 1
D3DDevice.DrawPrimitiveUP D3DPT_TRIANGLESTRIP, 2, MouseBox(0), Len(MouseBox(0))
D3DDevice.SetRenderState D3DRS_ALPHABLENDENABLE, 0 |  |  |  |  
                                        Not too
                                        horrible is it! The end result,
                                        including the texture blending examples
                                        will look like this:
                                         
                                        
                                         The strange 8-like figure over the
two left hand squares is the primitive rendered using the embedded alpha channel
method. Notice that there is no practical way of generating such a shape using
pure geometry, transparent texture and/or vertex/material based alpha blending. 
 Well, you've now completed another tutorial on the rocky road to Direct3D
success - with the techniques discussed here you should be perfectly capable of
rendering some cutting edge special effects - many of the weapon effects,
explosions, magic effects etc.. are rendered using a combination of these
techniques (amongst other things). You can download the working source code from
the top of the page, or from the downloads
page; and when your done you can move onto  Lesson 13 : Advanced Texturing
Part 2 (Texture pooling)
 |