Initial commit: add all skills files
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
63
shader-dev/reference/sdf-tricks.md
Normal file
63
shader-dev/reference/sdf-tricks.md
Normal file
@@ -0,0 +1,63 @@
|
||||
# SDF Tricks Detailed Reference
|
||||
|
||||
## Prerequisites
|
||||
- Understanding of signed distance fields and ray marching
|
||||
- Basic SDF primitives and boolean operations
|
||||
- FBM / procedural noise fundamentals
|
||||
|
||||
## Lipschitz Condition and FBM Detail
|
||||
|
||||
An SDF must satisfy the **Lipschitz condition**: `|f(a) - f(b)| ≤ |a - b|` (gradient magnitude ≤ 1). This guarantees that stepping by the SDF value is always safe — no surface exists within that radius.
|
||||
|
||||
When adding FBM noise to an SDF, the noise derivatives can violate Lipschitz:
|
||||
- Raw noise amplitude of 0.1 with frequency 20 has gradient ~2.0, breaking the condition
|
||||
- This causes ray marching to overshoot, creating holes and artifacts
|
||||
|
||||
**Solutions**:
|
||||
1. **Amplitude limiting**: Keep `amplitude × frequency < 1.0` across all octaves
|
||||
2. **Distance fade**: `d += amp * fbm(p * freq) * smoothstep(fadeStart, 0.0, d)` — detail only appears near the surface where overshoot distance is small
|
||||
3. **Step size reduction**: Multiply ray step by 0.5-0.7, trading speed for stability
|
||||
|
||||
## Bounding Volume Strategies
|
||||
|
||||
### Hierarchical Bounding
|
||||
For scenes with N objects, test bounding volumes in order of increasing cost:
|
||||
```
|
||||
Level 1: Scene bounding sphere (1 evaluation)
|
||||
Level 2: Object group bounds (few evaluations)
|
||||
Level 3: Individual object SDF (full cost)
|
||||
```
|
||||
|
||||
### Spatial Partitioning
|
||||
For repeating structures, combine domain repetition with bounds:
|
||||
```glsl
|
||||
float map(vec3 p) {
|
||||
vec3 q = mod(p + 2.0, 4.0) - 2.0; // repeat every 4 units
|
||||
// Only evaluate detail if within local bounding sphere
|
||||
float bound = length(q) - 1.5;
|
||||
if (bound > 0.2) return bound;
|
||||
return detailedSDF(q);
|
||||
}
|
||||
```
|
||||
|
||||
## Binary Search Convergence
|
||||
|
||||
After N iterations of binary search, the position error is `initialStep / 2^N`:
|
||||
- 4 iterations: 1/16 of initial step size
|
||||
- 6 iterations: 1/64 of initial step size (sub-pixel at typical resolutions)
|
||||
- 8 iterations: 1/256 (overkill for most uses)
|
||||
|
||||
6 iterations is the practical sweet spot — gives sub-pixel precision without wasting GPU cycles.
|
||||
|
||||
## XOR Operation Mathematics
|
||||
|
||||
`opXor(a, b) = max(min(a, b), -max(a, b))`
|
||||
|
||||
This is equivalent to: `union(a, b) AND NOT intersection(a, b)` — the symmetric difference. Geometry exists where exactly one shape is present but not both. Useful for creating lattice structures and interlocking patterns.
|
||||
|
||||
## Interior SDF Pattern Techniques
|
||||
|
||||
When the camera is inside an SDF (d < 0), the negative distance still gives useful information:
|
||||
- `abs(d)` gives distance to nearest surface from inside
|
||||
- Combine with repeating patterns using `fract()` to create infinite interior structures
|
||||
- Use `max(outerSDF, innerSDF)` to confine interior patterns within the outer shell
|
||||
Reference in New Issue
Block a user