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 ;)
|