diff options
| author | skal <pascal.massimino@gmail.com> | 2026-02-08 17:04:42 +0100 |
|---|---|---|
| committer | skal <pascal.massimino@gmail.com> | 2026-02-08 17:04:42 +0100 |
| commit | 5301e00826da6ff935bd42649f153d109eaef3b6 (patch) | |
| tree | bdff91a1bda4a19d106599f1a825aed06e2f8406 | |
| parent | afb04da1fc4780eed271064649377cf3e08d391f (diff) | |
feat(shaders): Add optimized 4-sample SDF normal estimation
Adds get_normal_fast() variant using tetrahedral gradient approximation.
Performance improvement:
- 4 SDF evaluations (vs 6 in get_normal_basic)
- ~33% fewer distance field samples
- Tetrahedron pattern: k.xyy, k.yyx, k.yxy, k.xxx where k=(1,-1)
Trade-off:
- Slightly less accurate than central differences method
- Good for real-time rendering where performance matters
- Same sphere optimization (analytical normal for obj_type == 1.0)
Parameters:
- epsilon: 0.0001 (vs 0.001 in basic method)
- Same interface: takes position and object params
Use case: Fast lighting calculations, performance-critical shaders
| -rw-r--r-- | assets/final/shaders/math/sdf_utils.wgsl | 16 |
1 files changed, 16 insertions, 0 deletions
diff --git a/assets/final/shaders/math/sdf_utils.wgsl b/assets/final/shaders/math/sdf_utils.wgsl index c2e49cf..3b06b93 100644 --- a/assets/final/shaders/math/sdf_utils.wgsl +++ b/assets/final/shaders/math/sdf_utils.wgsl @@ -9,6 +9,22 @@ fn get_normal_basic(p: vec3<f32>, obj_params: vec4<f32>) -> vec3<f32> { )); } +// Optimized normal estimation using tetrahedron pattern (4 SDF evals instead of 6). +// Slightly less accurate than central differences but faster. +// Uses tetrahedral gradient approximation with corners at (±1, ±1, ±1). +fn get_normal_fast(p: vec3<f32>, obj_params: vec4<f32>) -> vec3<f32> { + let obj_type = obj_params.x; + if (obj_type == 1.0) { return normalize(p); } + let eps = 0.0001; + let k = vec2<f32>(1.0, -1.0); + return normalize( + k.xyy * get_dist(p + k.xyy * eps, obj_params) + + k.yyx * get_dist(p + k.yyx * eps, obj_params) + + k.yxy * get_dist(p + k.yxy * eps, obj_params) + + k.xxx * get_dist(p + k.xxx * eps, obj_params) + ); +} + // Distance to an Axis-Aligned Bounding Box fn aabb_sdf(p: vec3<f32>, min_p: vec3<f32>, max_p: vec3<f32>) -> f32 { let center = (min_p + max_p) * 0.5; |
