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