The app showed only the camera clear color (grey srgb 43,44,47) — the
fullscreen quad's fragment shader produced no output. Two issues; the
second was the real blocker.
1. render/material.rs: skybox.wgsl declared binding 1 as texture_cube<f32>
but the material's #[texture(1)] defaulted to D2. The mismatched
bind-group layout vs. shader caused the pipeline to fail to specialize.
Fix: dimension = "cube" on the texture attribute so the layout matches.
2. SHADER COMPOSITION (the actual blocker): the shader was split across
naga_oil modules (ray_gen, geodesic, stars, disk, planets, grid, skybox)
pulled in via #import singularity::... This compiled and validated with
zero errors, but at runtime calling ANY cross-module-imported function
made the fragment output nothing (only the clear color showed). Local
functions were fine. Confirmed by bisecting a minimal repro with the
user watching the screen: local fn -> renders; imported fn (even pure
math) -> grey.
Rather than chase the naga_oil 0.22 / Bevy 0.19 composition bug, inline
every function into black_hole.wgsl and drop the #import singularity::*
lines. The 7 standalone module files are removed. Rendering now works.
Also fixes scene/planets.rs: upload_planets was allocating a fresh
ShaderBuffer (new handle) every frame, which re-triggered the
AsBindGroup RetryNextUpdate that the previous commit's startup pre-fill
was meant to eliminate. Now mutates the existing buffer asset in place
via set_data, keeping the handle stable.