| |
|
|
||||
![]() |
||||||
| |
|
|||||
|
Multitexturing in DirectX 6 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.
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.
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.
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.
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.
MODULATE2X The preceding
technique is called dark mapping rather than light mapping because the
resulting texel can only be a darker version of the unlit texel from the
primary map. For this reason, some applications use a variant of the modulate
technique, where the resulting texel is brightened by a factor of two
using the D3DTOP_MODULATE2X operation instead of D3DTOP_MODULATE. (This
can also be done in two passes using the alpha blending operation of Src*Dest
+ Dest*Src.)
In order to incorporate view-dependent reflection of light sources into the lighting model, a specular term is added to the view-independent (diffuse) term. In Direct3D, an application can provide the renderer with specular values at polygon vertices by passing them in the vertex structures. The interpolated specular colors are then added to the lighted texture color as shown in Figure 1. The problem with this method is that specular reflections tend to be fairly localized on an object, and their appearance can vary wildly depending on the tessellation of the object in the area of the specular reflection. Theoretically, the peak brightness of a traditional specular highlight can fall within a polygon (as in, not at a vertex), but this interpolation scheme doesn't reproduce such behavior. Figure 5A shows the artifacts caused by using vertex specular lighting. These artifacts are even more pronounced when the object and/or viewer are in motion.
Multitexturing
also lets you linearly blend between two textures for morphing effects.
You can use any of the D3DTOP_BLENDxALPHA operations, but D3DTOP_BLENDFACTORALPHA
or D3DTOP_BLENDDIFFUSEALPHA are most efficient for frame-to-frame variation
of the linear blend factor. A good example of using a linear blend for
morphing is the ATI Knight Demo, first shown at the CGDC in 1997 and illustrated
in Figure 6. In this example, the stone texture map on the knight statue
is the primary texture, and the "living" texture map is secondary. From
frame to frame during the morph, varying the blend factor causes the living
texture to fade in until it is the only texture visible. For efficiency,
before and after the morph, traditional single texture mapping is used
with the appropriate texture (Figures 6A and 6D).
What about plain old diffuse vertex lighting? As show in Figure 1, DirectX 6 has rolled the whole texture blending phase of the traditional pixel pipeline into the multiple texture mapping model. As a result, there is no separate texture blending render state like the one that existed in previous versions of Direct3D. Instead, the program needs to use a single texture operation unit to perform common vertex lighting. In order to use common vertex lighting on a single texture, program texture blending unit 0 as shown in Listing 2, but disable texture blending unit 1. Other Texture Operations What we've illustrated here are techniques that are likely to be of immediate use to developers, given the effects popular today and the capabilities of available hardware. Microsoft has provided illustrations of a variety of multitexturing effects and their multipass equivalents in the DirectX 6 SDK, though some of the single-pass versions of the techniques may not be supported by current or even next-generation hardware. Of course, users of Direct3D applications are likely to have cards with varying coverage of multitexture features (including no multitexturing features at all). How can an application determine the feature coverage of the hardware it is running on and use the most optimal multitexturing technique? Fortunately, the new API includes a means for validating the multitexturing techniques an application will use. In the next section, we cover this validation scheme as well as an architecture for incorporating fallback techniques so that an application will be able to take advantage of multitexturing hardware when it's available and robustly fall back to multipass techniques when it isn't. You'll note
that throughout this article, we've consistently referred to the new texture
abstraction as just that, an abstraction. The model, or abstraction, that's
illustrated here and documented in Microsoft's DirectX 6 SDK doesn't necessarily
map directly to the silicon designed by 3D video card makers. In fact,
in some cases, the silicon predates the API. Additionally, the full feature
set defined in the model isn't implemented on any 3D cards available to
date. As a result, programmers may initially find support of multiple
texture mapping modes somewhat sparse relative to the extreme flexibility
of the API. Microsoft has written a reference rasterizer for DirectX 6
that implements the full multiple texture mapping model; software developers
can use these to experiment with new effects. Also under DirectX 6, the
software rasterizer (not the same as the reference rasterizer) has support
for two texture operation units and a reasonable subset of the operations
defined by the API. MulTex can also serve as a tool for experimenting
with new techniques. For the foreseeable future, we recommend that developers
plan to implement both multipass and single-pass versions of techniques
in their titles, where the multipass code is executed when the application
is running on boards that cannot provide the desired functionality in
a single pass.
Chipsets with Multiple Texture Support At press time, the ATI Rage Pro and the 3Dfx Voodoo2 are the only shipping cards with multitexture support. So developers already have access to the first crop of available hardware. For up-to-date information, DirectX 6 drivers, and a list of which texture operations are supported, keep an eye on the developer support material on the ATI and 3Dfx web sites.
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|