DirectX SDK |
Applications often need to apply textures to geometry in a scene such that texels map directly to on-screen pixels. For example, take an application that needs to display text within a texture on an object within a scene. In order to clearly display textual information in a texture, the application needs some way to ensure that the textured geometry receives texels undisrupted by texture filtering. Failing this, the resulting image is often blurred, or in the case of point-sampled texture filtering, can cause rough edges.
Because the Direct3D pixel and texture sampling rules are carefully defined to unify pixel and texture sampling while supporting image and texture filtering, getting the texels in a texture to map directly to on-screen pixels can be a significant and often frustrating challenge. Overcoming this challenge requires a clear understanding of how Direct3D maps the floating-point texture coordinates for a vertex to the integer pixel coordinates used by the rasterizer.
Direct3D performs the following computations to map floating point texture coordinates into texel addresses is.
In the preceding formulas, Tx and Ty are the horizontal and vertical output texel coordinates, and u, v are the horizontal and vertical texture coordinates supplied for the vertex. The Mx and My elements represent the number of horizontal or vertical texels at the current mipmap level. (The remainder of this discussion targets horizontal mapping of texels to pixels; keep in mind that mapping in the vertical is identical to the horizontal case.)
Placing the texture coordinate limits 0.0 and 1.0 into these formulas maps a texture coordinate of 0.0 halfway between the first and last texels of a repeated texture map. The coordinate 1.0 is mapped halfway between the last texel of the current iteration of the texture map and the next iteration. For a repeated texture that's four texels wide, at mipmap level 0, the following illustration shows where the system maps the coordinates 0.0 and 1.0.
Given an understanding of this mapping, you can apply a simple bias to your screen-space geometry coordinates to force the system to map each texel to a corresponding pixel. For example, to draw a four-sided polygon (or "quad') that maps each texel from the preceding texture to one—and only one—pixel on the screen, you must force geometry coordinates to overlap the pixels, effectively placing the center of each texel at the center of each pixel. The result is the 1-to-1 mapping often sought-after by applications.
To map the texture (with a 4 texel width) to the pixel coordinates 0 through 3, you would draw a four-sided polygon (from two triangles) that have screen-space coordinates of –0.5 to 3.5, and texture coordinates of 0.0 to 1.0, respectively. For example, take the pixel at screen coordinate 0.0. Because 0.0 is one-half pixel away from the first vertex (at -0.5), and the total width is 4.0, the iterated texture coordinate is 0.125 (remember the formulas). Scaling this by the texture size, which is 4, gives 0.5. Subtracting the 0.5 bias produces a texture address of 0.0, which fully maps to the first texel in the map.
To summarize, texture coordinates overlap the texture map evenly on both sides. Given a texture of size 4, the mapping is as follows:
The system normalizes pixel coordinates in the same way it does texels, so if the vertices overlap the pixels into which you need to render, and the vertices use texture coordinates of 0.0 and 1.0, the two line up. If both are of similar size and properly aligned, they will match up exactly, texel to pixel, as shown in the following figure.