Skip to main content

loam_render/raymarch/
polytope_data.rs

1use loam_shape::polytope::Polytope4;
2use std::fmt::Write;
3
4/// Include the stubs only when neither extended polytope appears in the scene.
5pub fn polytope_stub_sdfs_wgsl() -> &'static str {
6    "fn cell120_sdf_local(p: vec4<f32>) -> f32 { return 1.0e9; }\n\
7     fn cell600_sdf_local(p: vec4<f32>) -> f32 { return 1.0e9; }\n"
8}
9
10/// Exact signed distance inside; a conservative distance bound outside.
11pub fn polytope_extended_sdfs_wgsl() -> String {
12    let mut source = String::with_capacity(48 * 1024);
13    for (shape, name) in [
14        (Polytope4::Cell120, "cell120"),
15        (Polytope4::Cell600, "cell600"),
16    ] {
17        let (normals, inradius) = shape.face_planes();
18        let count = normals.len();
19        let _ = writeln!(
20            source,
21            "const {name}_planes: array<vec4<f32>, {count}> = array("
22        );
23        for normal in normals {
24            let _ = writeln!(
25                source,
26                "    vec4<f32>({:.10}, {:.10}, {:.10}, {:.10}),",
27                normal.x, normal.y, normal.z, normal.w
28            );
29        }
30        source.push_str(");\n");
31        // Hart (1996), Sphere Tracing: the maximum of unit-plane distances is 1-Lipschitz.
32        let _ = writeln!(
33            source,
34            r#"
35fn {name}_sdf_local(p: vec4<f32>) -> f32 {{
36    var distance = -1.0e9;
37    for (var i = 0u; i < {count}u; i += 1u) {{
38        distance = max(distance, dot({name}_planes[i], p) - {inradius:.10});
39    }}
40    return distance;
41}}"#
42        );
43    }
44    source
45}