Reading — step 1 of 5
Read
Texture Sampling
A texture is a 2D image addressed by UV coordinates in [0, 1]: (0, 0) is one corner, (1, 1) the diagonally opposite one. To shade a pixel, you read the texel at the vertex-interpolated UV.
Getting from UV to pixel color sounds trivial — multiply by width/height, round, look up. The actual quality details:
Wrap mode: what happens when UV goes outside [0, 1]?
REPEAT:u = u mod 1(tiles).CLAMP:u = clamp(u, 0, 1)(stretches edges).MIRROR: alternates direction each unit.
Filter mode:
- Nearest:
tex[int(u * W)][int(v * H)]. Sharp / pixelated. Right for retro games and pixel art. - Bilinear: weight the four nearest texels by distance from the sample point. Smooth, no Moiré on slow camera motion.
Bilinear formula:
fx = u * W - 0.5 # texel center is at +0.5
fy = v * H - 0.5
x0 = floor(fx), x1 = x0 + 1
y0 = floor(fy), y1 = y0 + 1
ax = fx - x0
ay = fy - y0
c00 = tex[y0][x0]
c10 = tex[y0][x1]
c01 = tex[y1][x0]
c11 = tex[y1][x1]
top = lerp(c00, c10, ax)
bottom = lerp(c01, c11, ax)
sample = lerp(top, bottom, ay)
(Apply wrap mode to x0, x1, y0, y1 before lookup.)
Mipmaps: pre-filtered downsamples of the texture (tex/2, tex/4, tex/8, ...). When a triangle is far away, sampling the full-resolution texture aliases; instead you sample the mip level whose texel size matches the projected pixel size. mip_level = log2(max(d(u)/dx, d(v)/dy)) — derivatives the GPU computes automatically from the 2x2 pixel quad.
Anisotropic filtering: when a triangle is heavily foreshortened (a floor receding to the horizon), a normal mipmap blurs along the axis perpendicular to view. Aniso samples multiple texels along the elongated direction. 16x aniso is the high-end gold standard.
For now: nearest and bilinear with REPEAT wrap — enough to see textures on triangles.
Discussion
Ask a question, share an insight, or help someone who’s stuck.
Sign in to post a comment or reply.
Loading…