Description
Description
If a wgsl shader contains a function with fwidth
, dpdx
or dpdy
in it and that shader file is used as both a vertex and a fragment shader (just with different entry points), the shader fails in validation on WebGL even if the function is not used from the vertex shader.
i.e.
[[stage(vertex)]]
fn vertex(vertex: Vertex) -> VertexOutput {
var out: VertexOutput;
out.clip_position = view.view_proj * mesh.model * vec4<f32>(vertex.position, 1.0);
out.color = vertex.color;
return out;
}
struct FragmentInput {
[[location(0)]] color: vec4<f32>;
};
// compiler errors when vertex shader compiles
fn fwidth_wrapper(color: vec3<f32>) -> vec3<f32> {
return fwidth(color.rgb);
}
[[stage(fragment)]]
fn fragment(in: FragmentInput) -> [[location(0)]] vec4<f32> {
// return vec4<f32>(fwidth(in.color.rgb), in.color.a); // <-- this works
return vec4<f32>(fwidth_wrapper(in.color.rgb), in.color.a);
}
Repro steps
- Install wasm toolchain
- Check out https://github.com/johanhelsing/bevy/tree/wasm-fwidth-repro
cargo install wasm-server-runner
CARGO_TARGET_WASM32_UNKNOWN_UNKNOWN_RUNNER=wasm-server-runner cargo run --target wasm32-unknown-unknown --example mesh2d_manual
- Open browser link and observe console log output
Expected behavior
I'd expect to see a pretty dark star (with some color on it) in the middle of the browser window.
Observed behavior
No star,
panicked at 'wgpu error: Validation Error
Caused by:
In Device::create_render_pipeline
Internal error in VERTEX shader: ERROR: 0:44: 'fwidth' : no matching overloaded function found
ERROR: 0:803: 'fwidth' : no matching overloaded function found
Extra materials
For what it's worth, it works fine on native (cargo run --example mesh2d_manual
)
I don't understand the stack that well, but I assume this could be worked around by at some level trying to figure out whether fwidth
and friends is called from a function that is unreachable by the entry point and in that case skip it.
Platform
- WebGL, Firefox 97.0.1 Windows
- wgpu v0.12.0
Activity