I predict that DualTextureEffect will turn out to be the secret weapon in the armory of all the best looking Windows Phone games. It is efficient (only 7 vertex and 6 pixel shader instructions when not using fog), yet enables visually lush rendering techniques such as lightmaps and detail textures. For instance, the Harvest demo makes heavy use of DualTextureEffect.
DualTextureEffect samples from a pair of textures. Each has its own texture coordinates, so they can be independently aligned, tiled, rotated, etc. The textures are combined using Modulate2X blend mode:
output.rgb = Texture1.rgb * Texture2.rgb * 2;
output.a = Texture1.a * Texture2.a;
The easiest way to think about this operation is that the first texture defines the basic color of the object, which can then be adjusted by the second texture:
- Where the second texture contains 50% grey, the color is unchanged
- Where it is darker than 50%, the color is darkened
- Where it is brighter than 50%, the color becomes brighter
- If the second texture is not monochrome, the color is tinted accordingly
To use DualTextureEffect, you must:
- Have two texture coordinate channels in your vertex data (both TexCoord0 and TexCoord1)
- Set your model to use DualTextureEffect
- Set the DualTextureEffect.Texture2 property
- If you apply a multitexturing material in Max or Maya, you can export dual texture settings to FBX, and then when ModelProcessor.DefaultEffect is set to DualTextureEffect, it will automatically set up both textures for you
- Or you can do this in a custom content processor (again see the Reach Graphics Demo DualTextureProcessor)
- Or you can just manually set the Texture2 property at runtime
The idea behind lightmapping is simple. Instead of trying to compute lighting and shadows in realtime, you precompute them for an entire level, and store the results in one or more textures. These textures are uniquely mapped across the level, which means that every triangle gets its own unique area of the texture, with no tiling or texture reuse. Even with the largest textures that can fit in memory, the lightmap data typically ends up quite low resolution, but when you use DualTextureEffect to combine this with the base textures (which are usually tiled and thus appear to have higher resolution), the results can be stunning.
The big advantage of lightmaps is that because everything is precomputed, even the most complex lighting effects (soft shadows, radiosity, large numbers of lights, area lights, gobos, etc) can be rendered using even the weakest GPU hardware. Who cares if your crazy photon mapping algorithm takes hours on a high end workstation, when at runtime this will require just a simple texture fetch to display?
Of course the disadvantage is that because everything is precomputed, lightmaps only work for static models and static lighting. They are no use for things that animate.
Some people write their own code for generating lightmaps, and many game engines have lightmap generators built into their level editors. But the easiest way to get started is using a 3D modeling program: here are tutorials on how to render lightmaps with Max or Maya.
In the Reach Graphics Demo, our DualTextureEffect demo uses these simple base textures:
Combined with this lightmap, which we created in Maya:
The result is:
I wrote about detail textures a while ago, so won’t repeat the details here. Detail textures are a valuable technique for high resolution Xbox games, but less useful when targeting smaller phone screens.
The interesting thing is that from a runtime perspective, lightmaps and detail textures are exactly the same thing! The only difference is in the artwork. Lightmaps use a texture that is stretched just once over the world (so they provide very coarse color information), and are typically generated by programs, while detail textures are tiled many times (so they provide very fine color information), and are typically drawn by artists. But they use the exact same data formats and shader code, so once you set up a game to use DualTextureEffect, artists can choose whether they want lightmaps or detail textures just by changing their models!