Our Properties: Gamasutra GameCareerGuide IndieGames Indie Royale GDC IGF Game Developer Magazine GAO
My Message close
Contents
Multitexturing in DirectX 6
 
 
Printer-Friendly VersionPrinter-Friendly Version
 
Latest News
spacer View All spacer
 
February 8, 2012
 
DICE 2012: Is the publishing model broken? [6]
 
Double Fine launches $400K Kickstarter for Schafer-led adventure game [1]
 
Gameloft Live app takes on discoverability challenges
spacer
Latest Jobs
spacer View All     Post a Job     RSS spacer
 
February 8, 2012
 
Visceral Games Redwood Shores
Sr. Audio Artist-Visceral Games
 
Zindagi Games
Presentation/Game Programmer
 
2K Games
Public Relations Manager - 2K Games
 
Bigpoint
Front End UI Artist
 
Visceral Games Redwood Shores
Sr. Gameplay Engineer-Visceral Games
 
2K Marin
Level Designer
spacer
Latest Features
spacer View All spacer
 
February 8, 2012
 
arrow Postmortem: CyberConnect 2's Solatorobo: Red the Hunter
 
arrow Jerked Around by the Magic Circle - Clearing the Air Ten Years Later [30]
 
arrow Building the World of Reckoning [4]
 
arrow SPONSORED FEATURE: TwitchTV - How to Build Community Around Your Game in 2012 [13]
 
arrow Happy Action, Happy Developer: Tim Schafer on Reimagining Double Fine [9]
 
arrow Building an iOS Hit: Phase 1 [11]
 
arrow Postmortem: Appy Entertainment's SpellCraft School of Magic [5]
 
arrow Talking Copycats with Zynga's Design Chief [82]
spacer
Latest Blogs
spacer View All     Post     RSS spacer
 
February 8, 2012
 
The Devil Is in the Details of Action RPGs - Part One: The Logistics of Loot
 
Xbox LIVE Indie Games at it Again
 
Merging Waterfall and SCRUM [3]
 
Business Post Mortem: Wolf Toss: Pre-launch Planning & Blended CAC
 
Minmaxing - Is turn-based fun anymore? [53]
spacer
About
spacer Editor-In-Chief/News Director:
Kris Graft
Features Director:
Christian Nutt
Senior Contributing Editor:
Brandon Sheffield
News Editors:
Frank Cifaldi, Tom Curtis, Mike Rose, Eric Caoili, Kris Graft
Editors-At-Large:
Leigh Alexander, Chris Morris
Advertising:
Jennifer Sulik
Recruitment:
Gina Gross
 
Feature Submissions
 
Comment Guidelines
Sponsor
Features
  Multitexturing in DirectX 6
by Ian Bullard, Jason Mitchell, Michael Tatro []
Post A Comment Share on Twitter Share on Facebook RSS
 
 
October 9, 1998 Article Start Page 1 of 2 Next
 

 

One of the most interesting features introduced to Direct3D in the recent release of DirectX 6 is multiple texturing. Unfortunately, it's also one of the more confusing new features. This article will introduce multiple texture mapping into the context of the traditional pixel pipeline. We will describe the multitexture programming model, provide programming examples, and spend some time addressing the issues involved in robustly taking advantage of multitexturing hardware while maintaining fallback paths for application-level multipass methods. We have also created MulTex, a simulator that interactively illustrates this potentially puzzling new feature of Direct3D. Experimenting with MulTex is a good way to gain some familiarity with the texture blending abstraction. MulTex is available from the Game Developer web site and is definitely useful to have by your side as you read this article. (Mfctex, a similar tool written by Microsoft, ships with the Microsoft DirectX 6 SDK.)


The Traditional Pixel Pipeline

In previous versions of DirectX, the texture mapping phase of the Direct3D pixel pipeline has only involved fetching texels from a single texture. The two gray pipeline segments in Figure 1 are the stages in the traditional pipeline that deal with determining texel color and blending that color with the color of the primitive interpolated from the vertices. These two stages of the pipeline are replaced by the new multitexturing abstraction. The rest of the pipeline remains untouched.





pipeline
The pipeline.

 

DirectX 6 introduces the concept of a texture operation unit. Each unit may have a single texture associated with it, and up to eight texture operation units can be cascaded together to apply multiple textures to a common primitive. Each texture operation unit has six associated render states, which control the flow of pixels through the unit, as well as additional render states associated with filtering, clamping, and so on. Figure 2 shows two texture operation units cascaded together. We'll limit our discussion here to the dual texture case to keep things simple and because most of the near-term 3D hardware will support only two textures.

 

Texture examples
[zoom]

Figure 2. This screenshot, taken from the MulTex utility, shows two cascaded texture operation units.

 

Three of the render states in each texture operation unit are associated with RGB (color), and another three are associated with alpha. For RGB color, the render states D3DTSS_COLORARG1 and D3DTSS_COLORARG2 control arguments, while D3DTSS_COLOROP controls the operation on the arguments. Likewise, D3DTSS_ALPHAARG1 and D3DTSS_ALPHAARG2 control arguments to D3DTSS_ALPHAOP. Essentially, the D3DTSS_COLORx render states control the flow of an RGB vector, while the D3DTSS_ALPHAx render states govern the flow of the scalar alpha through parallel segments of the pixel pipeline, as shown in Figure 2.

Arguments

Using the argument states, you can direct input, such as interpolated diffuse color or texel color, into the texturing operations. Table 1 shows a complete list.

Table 1. DirectX 6 texturing operations.

D3DTA_TFACTOR Take pixel data from API-level factor. This factor is set with RENDERSTATE_TEXTUREFACTOR.
D3DTA_DIFFUSE Use interpolated diffuse color (Gouraud shading).
D3DTA_CURRENT Use color from previous texture operation unit.
D3DTA_TEXTURE Use color from texture associated with this unit.

Additionally, you can invert the arguments or replicate their alpha channel across the RGB channels. In the API, you can bitwise OR in the constants D3DTA_COMPLEMENT and D3DTA_ALPHAREPLICATE with any of these render states to achieve the desired effect. D3DTA_COMPLEMENT simply inverts each of the color channels, while D3DTA_ALPHAREPLICATE replicates the alpha from the argument across the R, G, and B channels. Naturally, the D3DTA_ALPHAREPLICATE flag isn't meaningful if it's used with D3DTSS_ALPHAARGx. Also, D3DTA_CURRENT doesn't make sense for the 0 texture operation unit because there is no previous texture operation unit.

 

The operators in each unit can operate on one or both of the corresponding arguments. The operator render states can be set to any of the values in Table 2.

This long list of operations may seem a bit daunting at first, but with some experimentation, the abstraction is actually quite approachable.

To get you started with the model, the next section illustrates some common multitexture techniques and how they can be programmed in DirectX 6. We suggest that you follow along with MulTex.

Each texture operation unit also has states for texture addressing and filtering associated with it. The application programmer can set these render states independently for each texture operation unit. A common example would be to set the base texture of an object, such as the brick texture in the following dark mapping example (Figure 3), to use D3DTADDRESS_WRAP texture addressing, while the texture operation unit for the dark map uses D3DTADDRESS_CLAMP.


Table 2. Operator render states.

D3DTOP_DISABLE Disable this and any later texture operation units
D3DTOP_SELECTARG1 Pass argument 1 untouched
D3DTOP_SELECTARG2 Pass argument 2 untouched
D3DTOP_MODULATE Multiply both arguments together
D3DTOP_MODULATE2X Multiply both arguments and shift 1 bit
D3DTOP_MODULATE4X Multiply both arguments and shift 2 bits
D3DTOP_ADD Add Arguments together
D3DTOP_ADDSIGNED Add Arguments with -0.5 bias
D3DTOP_ADDSIGNED2X Add Arguments with -0.5 bias and shift 1 bit
D3DTOP_SUBTRACT Subtract Arg2 from Arg1, with no saturation
D3DTOP_ADDSMOOTH Add arguments and subtract product
D3DTOP_BLENDDIFFUSEALPHA Blend arguments based on interpolated alpha
D3DTOP_BLENDTEXTUREALPHA Blend arguments based on texture alpha
D3DTOP_BLENDFACTORALPHA Blend arguments based on factor alpha
D3DTOP_BLENDTEXTUREALPHAPM Linear alpha blend with premultiplied Arg1 Arg1 + Arg2*(1-Alpha)
D3DTOP_BLENDCURRENTALPHA Blend arguments based on current alpha
D3DTOP_PREMODULATE Modulate with next texture before use
D3DTOP_MODULATEALPHA_ADDCOLOR Arg1.RGB + Arg1.A*Arg2.RGB
D3DTOP_MODULATECOLOR_ADDALPHA Arg1.RGB*Arg2.RGB + Arg1.A
D3DTOP_MODULATEINVALPHA_ADDCOLOR (1-Arg1.A)*Arg2.RGB + Arg1.RGB
D3DTOP_MODULATEINVCOLOR_ADDALPHA (1-Arg1.RGB)*Arg2.RGB + Arg1.A
D3DTOP_BUMPENVMAP Per pixel environment map perturbation
D3DTOP_BUMPENVMAPLUMINANCE Environment map perturbation w/luminance channel
D3DTOP_DOTPRODUCT3 A per-pixel dot product that could be used for specification of surface normal vector data in texture maps. The result is (Arg1.R*Arg2.R + Arg1.G*Arg2.G + Arg1.B*Arg2.B) where each component is scaled and offset to make it signed.

 

 

Dark mapping
[zoom]

Figure 3. Dark mapping in action.

 

Dark Mapping

Naturally, our first example of multiple texture mapping is the dark map described by Brian Hook in the August 1997 issue of Game Developer ("Multipass Rendering and the Magic of Alpha Rendering"). Dark mapping is commonly used in lieu of vertex lighting, where one of the two textures contains an unlit base texture and the other contains a lighting texture (the dark map). Using the new multiple texturing API, one might implement this technique as shown in Figure 2.

In the figure, the two large blue boxes represent texture operation units, and the red lines show the flow of data through the pipeline. The first texture operation unit merely passes data from texture 0 to the next stage. The second texture operation unit receives these texels via Arg2 and also fetches texels from texture 1 via Arg1. The results are modulated, giving the final texel color as shown on the right-hand side of Figure 3. Nothing interesting is being done with the alpha channel of the pipeline in this case. Code (generated by MulTex) for dark mapping is shown in Listing 1.

Listing 1. Dark mapping. In this code snippet, unspecified render states are left in their default states for brevity. In practice, an application should be more defensive than this.

						// Program Stage 0:
			lpDev->SetTexture(0, pTex0 );
			lpDev->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
			lpDev->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
			// Program Stage 1:
			lpDev->SetTexture(1, pTex1 );
			lpDev->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
			lpDev->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT);
			lpDev->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MODULATE);
			
 
Article Start Page 1 of 2 Next
 
Comments


none
 
Comment:
 




UBM Techweb
Game Network
Game Developers Conference | GDC Europe | GDC Online | GDC China | Gamasutra | Game Developer Magazine | Game Advertising Online
Game Career Guide | Independent Games Festival | Indie Royale | IndieGames

Other UBM TechWeb Networks
Business Technology | Business Technology Events | Telecommunications & Communications Providers

Privacy Policy | Terms of Service | Contact Us | Copyright © UBM TechWeb, All Rights Reserved.