fix(web): use textureSampleLevel for skybox to satisfy Tint's uniform-flow rule
The web build black-screened on the first frame: the black-hole fragment
shader failed to compile in Chrome's Tint (BrowserWebGpu backend) with
"'textureSample' must only be called from uniform control flow", which
invalidated the opaque_mesh2d_pipeline and made Bevy quit after frame 1.
Desktop (naga) was unaffected because naga does not enforce this WGSL rule,
which is why the regression was web-only.
skybox_color() called textureSample on the cubemap from inside the main RK45
integration loop. That loop's control flow is non-uniform — per-pixel early
exit via `if (accum_alpha > 0.99) { break; }` and per-iteration accept/reject
— and textureSample needs screen-space derivatives (uniform across the quad)
for mip selection, so the spec forbids it there.
Switch to textureSampleLevel with an explicit LOD of 0. textureSampleLevel
does no derivative computation and is permitted in non-uniform control flow.
LOD 0 is correct for the skybox: it is sampled at full resolution with no
mip minification, so the visual result is identical to the implicit-lod path.
Diagnosis required building a JS-side probe that fetches the WGSL, mirrors
naga_oil preprocessing (resolve #{MATERIAL_BIND_GROUP}, inline VertexOutput),
then calls device.createShaderModule + getCompilationInfo to surface Tint's
structured messages — Bevy's wgpu path swallows the raw Tint error on web and
only ever surfaces the downstream "Invalid ShaderModule due to a previous
error". The probe confirmed the error site and rule; it is not committed.
This commit is contained in:
parent
00aa27175e
commit
5c0b1db01b
@ -145,8 +145,17 @@ fn star_color(dir: vec3<f32>, intensity: f32) -> vec3<f32> {
|
||||
}
|
||||
|
||||
// --- skybox ---
|
||||
// textureSampleLevel (not textureSample) is REQUIRED here: this is called from
|
||||
// inside the main RK45 integration loop, whose control flow is non-uniform
|
||||
// (`if (accum_alpha > 0.99) { break; }`, per-pixel early exit). The WGSL spec
|
||||
// forbids textureSample outside uniform control flow because it needs
|
||||
// screen-space derivatives for mip selection; Chrome's Tint enforces this and
|
||||
// rejects the shader, while naga (desktop) does not — which is why this only
|
||||
// crashed the web build. textureSampleLevel takes an explicit LOD (0 here: the
|
||||
// skybox cubemap is sampled at full resolution, no mip minification) and is
|
||||
// permitted in non-uniform flow. The visual result is identical.
|
||||
fn skybox_color(dir: vec3<f32>) -> vec3<f32> {
|
||||
return textureSample(skybox, skybox_sampler, dir).rgb;
|
||||
return textureSampleLevel(skybox, skybox_sampler, dir, 0.0).rgb;
|
||||
}
|
||||
|
||||
// --- geodesic ---
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user