Files
skills/shader-dev/reference/camera-effects.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

81 lines
3.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Camera Effects Detailed Reference
## Prerequisites
- Ray marching fundamentals (ray origin, ray direction)
- Multipass buffers (for accumulation-based DoF)
- Hash functions for stochastic sampling
## Thin Lens Model Derivation
A real camera lens focuses light from a focal plane onto the sensor. Points not on the focal plane project to a **circle of confusion (CoC)** on the sensor.
### Circle of Confusion Formula
```
CoC = |S2 - S1| × A × f / (S1 × (S2 - f))
```
Where:
- `S1` = focal distance (distance to in-focus plane)
- `S2` = object distance
- `A` = aperture diameter
- `f` = focal length
### Simplified for Shaders
```
CoC ≈ apertureSize × |depth - focalDistance| / depth
```
### Ray-Based Implementation
Instead of computing CoC per pixel, we model the physical process:
1. Choose a random point on the aperture disk → new ray origin
2. The focal point (where the original ray hits the focal plane) stays fixed
3. New ray direction = `normalize(focalPoint - newOrigin)`
4. Average many such samples → natural bokeh with correct occlusion
### Aperture Shape
- Circular: `vec2 p = sqrt(r) * vec2(cos(a), sin(a))` — uniform disk
- Polygonal: reject samples outside polygon for hexagonal/octagonal bokeh
- The `sqrt(r)` is critical for uniform distribution (area-preserving)
## Poisson Disk Sampling
Pre-computed 16-point Poisson disk for blur kernels:
```glsl
const vec2 poissonDisk[16] = vec2[](
vec2(-0.94201624, -0.39906216), vec2(0.94558609, -0.76890725),
vec2(-0.09418410, -0.92938870), vec2(0.34495938, 0.29387760),
vec2(-0.91588581, 0.45771432), vec2(-0.81544232, -0.87912464),
vec2(-0.38277543, 0.27676845), vec2(0.97484398, 0.75648379),
vec2(0.44323325, -0.97511554), vec2(0.53742981, -0.47373420),
vec2(-0.26496911, -0.41893023), vec2(0.79197514, 0.19090188),
vec2(-0.24188840, 0.99706507), vec2(-0.81409955, 0.91437590),
vec2(0.19984126, 0.78641367), vec2(0.14383161, -0.14100790)
);
```
Advantages over regular grid: no structured aliasing patterns, better coverage per sample count.
## Motion Blur Approaches
### Stochastic Time Sampling (Ray Marching)
For each pixel, pick a random time within the shutter interval:
```
t_sample = iTime + (rand - 0.5) * shutterDuration
```
Use `t_sample` for all scene animation. Accumulate multiple frames for convergence.
### Velocity Buffer (Post-Process)
1. Render scene + store per-pixel velocity vectors
2. For each pixel, sample along the velocity direction
3. Weight samples by distance from center (triangle filter)
### Hybrid
Use temporal accumulation (TAA-style) with per-frame time jitter — converges over frames with no per-frame cost increase.
## Film Grain Characteristics
Real film grain properties:
- **Luminance-dependent**: More visible in shadows, less in highlights
- **Temporally varying**: Different pattern each frame (use `fract(iTime)` in hash seed)
- **Spatially uncorrelated**: Use pixel coordinates in hash, not UV (grain should be screen-resolution)
- **Intensity**: 0.02-0.05 for subtle, 0.1+ for stylized/vintage look