A texture is an array of values, where each value is a set of numbers (components) describing the attributes of a texture element, or texel. For the Nintendo 64, the numbers representing a texel are fixed-point. The number of components per pixel and the number of bits per component is variable. Section 14-6 "Color Index Frame Buffer" describes the possible formats for texels.
When displaying a texture on the screen of a display, we must perform a mapping from the texture space to the display image space. In the case of texture rectangles, where the geometric operations are limited to scaling and translation, the main problem is how to sample and filter the source texture so that it is faithfully produced on the display. Figure 14-2 is one example of aliasing artifacts that can effect image quality. In this example, 10 black bars are separated by 10 white bars with even spacing. The bars cover a width of 11 pixels on the screen. Because we are sampling at a lower frequency than the texture, our output image is aliased. Aliasing artifacts are caused by high-frequency information that is insufficiently sampled appearing as low-frequency information. Furthermore, if the beginning sample point is moved slightly, the sampled image can shift dramatically. During animations this causes the displayed image to scintillate or flash. Nyquist's Law indicates that the sampling frequency should be greater than twice the highest frequency component in the texture to avoid aliasing artifacts.
Point sampling in the Nintendo 64 means that we assume that each texel maps to one pixel on the display, and we ignore any fractional overlap between texels and pixels. Execute the following commands to enable point sampling.
gsDPSetTextureFilter(G_TF_POINT)
Point sampling works well for mapping a rectangular texture to a screen-aligned rectangle of the same size on the display. Problems occur if the sampling ratio is not 1:1, however, as shown in Figure 14-3. In the first case, we display 10 texels using 10 pixels. In the second case, we scale the image slightly by displaying 9 texels on 10 pixels. This results in the middle pixel having the same color as the previous bar. In general, point sampled images should be scaled by an integer power of two to avoid this problem. To achieve other scalings, it is necessary to use bilinear filtering.
gsDPSetTextureFilter(G_TF_POINT), gsSPTextureRectangle(50<<2,50<<2,150<<2,150<<2, G_TX_RENDERTILE, 0,0, 1<<10,1<<10), gsSPTextureRectangle(60<<2,60<<2,160<<2,160<<2, G_TX_RENDERTILE, 0,0, 1<<9,1<<9), gsSPTextureRectangle(70<<2,70<<2,170<<2,170<<2, G_TX_RENDERTILE, 0,0, 1<<8,1<<8),
Point sampling also implies that animated sprites will have to move in one-pixel increments. Even though the rectangle can be positioned with 2 bits of sub pixel precision, and the texture can be offset to 5 bits of fractional precision, the point sampling only looks at the integer coordinate and so will not change until there is at least a one pixel change in position. Bilinear filtering allows for smoother motion of sprites.
Instead of selecting a single texel for a given pixel, as in point sampling, bilinear filtering selects four texels surrounding the sample point and interpolates these points using fractional position information to determine the pixel color. The following command shows how to enable bilinear filtering.
gsDPSetTextureFilter(G_TF_BILERP)
An example of bilinear filtering is shown in Figure 14-4.
In the Nintendo 64, rather than doing a full bilinear interpolation using all four samples, a triangular interpolation is performed that uses only three points. The texture filter selects which three points to use depending on where the sample point lies inside the 2x2 grid of texels. In certain cases, the triangular filter can cause small anomalies. These cases occur when there are drastic intensity changes from one texel to another in the texture as shown in Figure 14-5. In this example, if the sampling point moves slightly from one side of the diagonal to the other, the resulting color changes abruptly. In general, it is best to prefilter an image so that these sharp texture edges at least a slight intensity ramp.
With bilinear filtering, it is possible to scale a texture without the problems of point sampling. Example 14-6 shows a texture rectangle with the texture scaled by 1.5 in S and T:
gsDPSetTextureFilter(G_TF_BILERP), gsSPTextureRectangle(50<<2,50<<2,150<<2,150<<2, G_TX_RENDERTILE, 0,0, 3<<9,3<<9),
Smooth scrolling of texture rectangles is discussed in Section 14.2.5 "Smooth Scrolling".
There is a special case in which the texture filter can perform an exact average using all four texels. This case occurs when the sample point lies exactly in the center, i.e. s_frac = t_frac = 0.5. To enable the average mode, use the command:
gsDPSetTextureFilter(G_TF_AVERAGE)
In order to force the sample point to be in the middle of the texel, set the start point to 0.5 and then proceed texture rendering by 1 texel per pixel. Example 14-8 demonstrates this:
gsDPSetTextureFilter(G_TF_AVERAGE), gsSPTextureRectangle(50<<2,50<<2,150<<2,150<<2, G_TX_RENDERTILE, 1<<4,1<<4, 1<<10,1<<10),
Copy mode is a special pipeline mode that allows fast image copies to the framebuffer. Copy mode can be enabled as shown in the following command.
gsDPSetCycleType(G_CYC_COPY)
In copy mode, four horizontally adjacent texels are copied per clock as shown in Figure 14-6.
In copy mode, since four texels are copied each clock, the step in S per clock must be set to four. The following example shows a texture rectangle using copy mode.
gsDPSetCycleType(G_CYC_COPY), gsSPTextureRectangle(50<<2,50<<2,150<<2,150<<2, G_TX_RENDERTILE, 0,0, 4<<10,1<<10),
Since copy mode bypasses most of the RDP pipeline, the filter settings are not used. However, it is still necessary to disable perspective correction as shown in Example 14-2. Also, copy mode is not valid for all texture types.
It is possible to scale textures in copy mode in the T(Y) direction only. Note that in this case, the rules for point sampled scaling apply, only integer power of two scalings.
In copy mode, textures are copied directly to memory, so there is no opportunity for color combiner operations, filtering, transparency, etc. Copying is a write-only operation so transparency using the normal blending hardware is impossible. However, you can achieve "cutout" and "dithered" types of transparency using the alpha compare logic. Please see Section 15.5.4 "Alpha Compare Calculation".