diff options
Diffstat (limited to 'assets/final/shaders')
| -rw-r--r-- | assets/final/shaders/math/sdf_utils.wgsl | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/assets/final/shaders/math/sdf_utils.wgsl b/assets/final/shaders/math/sdf_utils.wgsl index 3b06b93..660a4ce 100644 --- a/assets/final/shaders/math/sdf_utils.wgsl +++ b/assets/final/shaders/math/sdf_utils.wgsl @@ -25,6 +25,87 @@ fn get_normal_fast(p: vec3<f32>, obj_params: vec4<f32>) -> vec3<f32> { ); } +// Bump-mapped normal using central differences (6 samples: SDF + texture). +// High quality, suitable for detailed surfaces with displacement mapping. +// Note: Requires spherical_uv() function and get_dist() to be available in calling context. +fn get_normal_bump( + p: vec3<f32>, + obj_params: vec4<f32>, + noise_tex: texture_2d<f32>, + noise_sampler: sampler, + disp_strength: f32 +) -> vec3<f32> { + let e = vec2<f32>(0.005, 0.0); + + let q_x1 = p + e.xyy; + let uv_x1 = spherical_uv(q_x1); + let h_x1 = textureSample(noise_tex, noise_sampler, uv_x1).r; + let d_x1 = get_dist(q_x1, obj_params) - disp_strength * h_x1; + + let q_x2 = p - e.xyy; + let uv_x2 = spherical_uv(q_x2); + let h_x2 = textureSample(noise_tex, noise_sampler, uv_x2).r; + let d_x2 = get_dist(q_x2, obj_params) - disp_strength * h_x2; + + let q_y1 = p + e.yxy; + let uv_y1 = spherical_uv(q_y1); + let h_y1 = textureSample(noise_tex, noise_sampler, uv_y1).r; + let d_y1 = get_dist(q_y1, obj_params) - disp_strength * h_y1; + + let q_y2 = p - e.yxy; + let uv_y2 = spherical_uv(q_y2); + let h_y2 = textureSample(noise_tex, noise_sampler, uv_y2).r; + let d_y2 = get_dist(q_y2, obj_params) - disp_strength * h_y2; + + let q_z1 = p + e.yyx; + let uv_z1 = spherical_uv(q_z1); + let h_z1 = textureSample(noise_tex, noise_sampler, uv_z1).r; + let d_z1 = get_dist(q_z1, obj_params) - disp_strength * h_z1; + + let q_z2 = p - e.yyx; + let uv_z2 = spherical_uv(q_z2); + let h_z2 = textureSample(noise_tex, noise_sampler, uv_z2).r; + let d_z2 = get_dist(q_z2, obj_params) - disp_strength * h_z2; + + return normalize(vec3<f32>(d_x1 - d_x2, d_y1 - d_y2, d_z1 - d_z2)); +} + +// Optimized bump-mapped normal using tetrahedron pattern (4 samples instead of 6). +// 33% faster than get_normal_bump(), slightly less accurate. +// Suitable for real-time rendering with displacement mapping. +fn get_normal_bump_fast( + p: vec3<f32>, + obj_params: vec4<f32>, + noise_tex: texture_2d<f32>, + noise_sampler: sampler, + disp_strength: f32 +) -> vec3<f32> { + let eps = 0.0005; + let k = vec2<f32>(1.0, -1.0); + + let q1 = p + k.xyy * eps; + let uv1 = spherical_uv(q1); + let h1 = textureSample(noise_tex, noise_sampler, uv1).r; + let d1 = get_dist(q1, obj_params) - disp_strength * h1; + + let q2 = p + k.yyx * eps; + let uv2 = spherical_uv(q2); + let h2 = textureSample(noise_tex, noise_sampler, uv2).r; + let d2 = get_dist(q2, obj_params) - disp_strength * h2; + + let q3 = p + k.yxy * eps; + let uv3 = spherical_uv(q3); + let h3 = textureSample(noise_tex, noise_sampler, uv3).r; + let d3 = get_dist(q3, obj_params) - disp_strength * h3; + + let q4 = p + k.xxx * eps; + let uv4 = spherical_uv(q4); + let h4 = textureSample(noise_tex, noise_sampler, uv4).r; + let d4 = get_dist(q4, obj_params) - disp_strength * h4; + + return normalize(k.xyy * d1 + k.yyx * d2 + k.yxy * d3 + k.xxx * d4); +} + // 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; |
