Please support our sponsor:
DirectX4VB.Com - All You Need For Multimedia Visual Basic Programming

Main Site Links Resources Tutorials
News VB Gaming Code Downloads DirectX 7
Contact Webmaster VB Programming Product Reviews DirectX 8
  General Multimedia Articles DirectX 9
      Miscellaneous

 

Immediate Mode: Multipass Texture Blending
By: Jack Hoxley
Written: August 2000
Download:
IM_Multipass.Zip (54kb) IM_TexBlend.Zip (97kb)


Texture blending is an extremely cool effect - often used to simulate special effects, and often used to create light mapping. There are two types of texture blending supported by DirectX - Multipass, and straight blending. Multipass blending is extremely easy but somewhat slower when applied to complex geometry, and straight blending is faster but requires hardware support for it to work. Many games design their engines so that if the hardware supports straight blending it uses that - otherwise it uses multipass blending.

This tutorial deals with mult-pass texture blending. All that is done with multipass blending is you drawing the same primative at the same location multiple times but with a different texture each time. For example, if you had a square (with 4 vertices) and wanted to blend 3 times you would have to draw 12 vertices; which is why it gets slow when using complex geometry - 250 vertices quickly becomes 500-1000 vertices. To blend multiple textures you follow this simple pattern:

1. Setup blending options and vertices
2. Apply a texture to the device
3. Draw the primative
4. Apply another texture to the device
5. Draw the primative again
- - And repeat 2,3,4,5 until all texture layers have been rendered

Light mapping is often done through this technique. If you use normal direct3D lighting it calculates the light colour on a per-vertex basis, this is fine 70% of the time, but when you have large planes where the vertices are a long way apart you start getting some unrealistic lighting. See the theory piece on lighting for more details about the Direct3D lighting engine. To solve this problem many people use lightmaps. Lightmaps tend to be greyscale textures that when blended with the normal texture (say a brick wall) give the impression of lighting. Take a look at these three pictures:

+ =

The greyscale gradient acts as a light source - bright in the middle, fading to no light at the edges. Because it's only a picture it can be any shape you like - it doesn't have to be circular, it could even be a logo. The lightmap doesn't have to be greyscale - if it were blue it would only enhance the blue parts of the source image; the light is only as good as your imagination and/or drawing capabilities ...

So, how's this done?

We'll be using a modified version of Carls D3DIM Tutorial 01 source code, read the proper tutorial here if you haven't already. We need to create two textures, done through a wrapper function that you can look at in the downloadable source:

Set Texture0 = CreateTexture(App.Path & "\Texture0.bmp", 128, 128)
Set Texture1 = CreateTexture(App.Path & "\Texture1.bmp", 128, 128)

We then need to set up the rendering options

'Bilinear texture filtering - smooths out the texture and reduces some of the "jaggies" that appear
Device.SetTextureStageState 0, D3DTSS_MAGFILTER, D3DTFG_LINEAR
Device.SetTextureStageState 0, D3DTSS_MINFILTER, D3DTFN_LINEAR

'We need to set the destination and source blending factors - as they are here is fine for lightmaps.
'Straight blending should have them both set to "D3DBLEND_ONE"... Search the object browser (F2 in the IDE)
'for CONST_D3DBLEND for the other options...

Device.SetRenderState D3DRENDERSTATE_DESTBLEND, D3DBLEND_SRCCOLOR
Device.SetRenderState D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE

Now we skip straight to the render loop:

Device.SetRenderState D3DRENDERSTATE_ALPHABLENDENABLE, True
Call Device.SetTexture(0, Texture0)
Call Device.DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_TLVERTEX, Tile3(0), 4, D3DDP_WAIT)
'You could alter the texture coordinates at this point - to create yet more effects
Call Device.SetTexture(0, Texture1)
Call Device.DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_TLVERTEX, Tile3(0), 4, D3DDP_WAIT)

This Code excerpt would do two passes - you can add as many as you like - but rememeber you are doubling the render time for this primative for almost every pass...

Done. You can now do multi-pass texture blending, no too hard really? Any question go to the usual place... You can download the source code from the top of the page, or from the downloads page. There's also an additional demo thats quite pretty to look at ;)

DirectX 4 VB © 2000 Jack Hoxley. All rights reserved.
Reproduction of this site and it's contents, in whole or in part, is prohibited,
except where explicitly stated otherwise.
Design by Mateo
Contact Webmaster
This site is hosted by Exhedra Solutions, Inc., the parent company of RentACoder.com and PlanetSourceCode.com