Files
skills/shader-dev/techniques/texture-mapping-advanced.md
shihao 6487becf60 Initial commit: add all skills files
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 16:52:49 +08:00

122 lines
4.3 KiB
Markdown

# Advanced Texture Mapping Techniques
## Use Cases
- Texturing 3D surfaces without UV seams (triplanar/biplanar mapping)
- Eliminating visible tiling repetition on large surfaces
- Proper texture filtering in ray-marched scenes (mip-level selection)
- Combining procedural and sampled textures
## Techniques
### 1. Biplanar Mapping (Optimized Triplanar)
Uses only 2 texture fetches instead of 3, selecting the two most relevant projection axes:
```glsl
vec4 biplanar(sampler2D sam, vec3 p, vec3 n, float k) {
vec3 dpdx = dFdx(p);
vec3 dpdy = dFdy(p);
n = abs(n);
// Determine major, minor, median axes
ivec3 ma = (n.x > n.y && n.x > n.z) ? ivec3(0,1,2) :
(n.y > n.z) ? ivec3(1,2,0) : ivec3(2,0,1);
ivec3 mi = (n.x < n.y && n.x < n.z) ? ivec3(0,1,2) :
(n.y < n.z) ? ivec3(1,2,0) : ivec3(2,0,1);
ivec3 me = ivec3(3) - mi - ma;
// Two texture fetches (major and median projections)
vec4 x = textureGrad(sam, vec2(p[ma.y], p[ma.z]),
vec2(dpdx[ma.y], dpdx[ma.z]),
vec2(dpdy[ma.y], dpdy[ma.z]));
vec4 y = textureGrad(sam, vec2(p[me.y], p[me.z]),
vec2(dpdx[me.y], dpdx[me.z]),
vec2(dpdy[me.y], dpdy[me.z]));
// Blend weights with local support
vec2 w = vec2(n[ma.x], n[me.x]);
w = clamp((w - 0.5773) / (1.0 - 0.5773), 0.0, 1.0); // 0.5773 = 1/sqrt(3)
w = pow(w, vec2(k / 8.0));
return (x * w.x + y * w.y) / (w.x + w.y);
}
// Usage: vec4 col = biplanar(tex, worldPos * scale, worldNormal, 8.0);
```
**Why biplanar over triplanar**: Saves one texture fetch (bandwidth-bound advantage), with k=8 visually equivalent to triplanar. The `dFdx/dFdy` gradient propagation prevents mipmap seams at axis-switching boundaries.
### 2. Texture Repetition Avoidance
Three approaches to eliminate visible tiling patterns:
#### Method A: Per-Tile Random Offset (4 fetches)
```glsl
vec4 textureNoTile(sampler2D sam, vec2 uv) {
vec2 iuv = floor(uv);
vec2 fuv = fract(uv);
// Generate 4 random offsets for the 4 surrounding tiles
vec4 ofa = hash42(iuv + vec2(0, 0));
vec4 ofb = hash42(iuv + vec2(1, 0));
vec4 ofc = hash42(iuv + vec2(0, 1));
vec4 ofd = hash42(iuv + vec2(1, 1));
// Transform UVs per tile
vec2 uva = uv + ofa.xy;
vec2 uvb = uv + ofb.xy;
vec2 uvc = uv + ofc.xy;
vec2 uvd = uv + ofd.xy;
// Blend near borders with smooth weights
vec2 b = smoothstep(0.25, 0.75, fuv);
return mix(mix(texture(sam, uva), texture(sam, uvb), b.x),
mix(texture(sam, uvc), texture(sam, uvd), b.x), b.y);
}
```
#### Method B: Virtual Pattern (2 fetches, cheapest)
```glsl
vec4 textureNoTileCheap(sampler2D sam, vec2 uv) {
float k = texture(iChannel1, 0.005 * uv).x; // low-freq variation index
float index = k * 8.0;
float i = floor(index);
float f = fract(index);
// Two offset lookups based on index
vec2 offa = sin(vec2(3.0, 7.0) * (i + 0.0));
vec2 offb = sin(vec2(3.0, 7.0) * (i + 1.0));
return mix(texture(sam, uv + offa), texture(sam, uv + offb), smoothstep(0.2, 0.8, f));
}
```
### 3. Ray Differential Texture Filtering
For ray-marched scenes, compute proper mip levels using ray differentials:
```glsl
// After finding hit point pos with normal nor:
// 1. Compute neighbor pixel ray directions
vec3 rdx = normalize(rd + dFdx(rd)); // x-neighbor ray
vec3 rdy = normalize(rd + dFdy(rd)); // y-neighbor ray
// 2. Intersect neighbors with tangent plane at hit point
float dt_dx = -dot(pos - ro, nor) / dot(rdx, nor);
float dt_dy = -dot(pos - ro, nor) / dot(rdy, nor);
vec3 posDx = ro + rdx * dt_dx;
vec3 posDy = ro + rdy * dt_dy;
// 3. World-space position derivatives = pixel footprint
vec3 dposdx = posDx - pos;
vec3 dposdy = posDy - pos;
// 4. Transform to texture derivatives and use textureGrad
// For simple planar mapping (e.g. ground plane):
vec2 duvdx = dposdx.xz * textureScale;
vec2 duvdy = dposdy.xz * textureScale;
vec4 color = textureGrad(tex, pos.xz * textureScale, duvdx, duvdy);
```
This provides correct mip-level selection for procedural and sampled textures on ray-marched surfaces, eliminating shimmer and aliasing at distance.
→ For deeper details, see [reference/texture-mapping-advanced.md](../reference/texture-mapping-advanced.md)