Texture Mapping
Texture mapping applies a 2D image (texture) to the surface of a 3D object. Each vertex of the mesh is assigned UV coordinates that map to a position on the texture.
UV Coordinates
Texture Space:
(0,0) ---------------------- (1,0)
| |
| Texture Image |
| |
| |
(0,1) ---------------------- (1,1)
U = horizontal axis (0 to 1)
V = vertical axis (0 to 1)
Triangle with UV mapping:
V0 (pos, uv=(0,0)) โ top-left of texture
V1 (pos, uv=(1,0)) โ top-right
V2 (pos, uv=(0,1)) โ bottom-left
Interpolation:
uv(P) = ฮป0*uv(V0) + ฮป1*uv(V1) + ฮป2*uv(V2)
texel = texture.sample(uv(P))
Texture Sampling
Nearest Neighbor:
Pick the closest texel (pixel in texture)
Fast but blocky/pixelated
uv = (0.3, 0.7)
texel = texture[floor(uv.x * width)][floor(uv.y * height)]
Bilinear Interpolation:
Average 4 nearest texels weighted by distance
Smoother but slightly slower
u0 = floor(u), u1 = u0 + 1
v0 = floor(v), v1 = v0 + 1
fu = u - u0, fv = v - v0
color = (1-fu)*(1-fv)*tex(u0,v0)
+ fu*(1-fv)*tex(u1,v0)
+ (1-fu)*fv*tex(u0,v1)
+ fu*fv*tex(u1,v1)
Texture Wrapping
Repeat:
u = fract(u) // wraps around
Good for tiling patterns
Clamp:
u = clamp(u, 0, 1)
Edges extend to border color
Mirror:
Alternates between normal and flipped
Prevents visible seams at edges
Mipmapping
Precomputed texture pyramid at multiple resolutions. Reduces aliasing and improves performance for distant objects.
Mipmap levels:
Level 0: 1024x1024 (original)
Level 1: 512x512
Level 2: 256x256
Level 3: 128x128
...
Level N: 1x1
Choose level based on screen footprint:
L = log2(d) where d = texture size in pixels on screen
Trilinear filtering:
Interpolate between two nearest mip levels
Smooth across distance changes
Normal Mapping
Uses a texture to modify surface normals, adding detail without increasing geometry. The RGB values of the normal map encode the normal direction.
Normal Map:
R = x-component of normal (mapped from [-1,1] to [0,255])
G = y-component of normal
B = z-component of normal
n_map = texture.sample(uv) * 2 - 1
Transform to world space using TBN matrix:
T = tangent
B = bitangent
N = surface normal
TBN = [T, B, N]
world_normal = TBN * n_map