bevy/crates/bevy_render/src/instance_index.wgsl

18 lines
593 B
WebGPU Shading Language
Raw Normal View History

Work around naga/wgpu WGSL instance_index -> GLSL gl_InstanceID bug on WebGL2 (#9383) naga and wgpu should polyfill WGSL instance_index functionality where it is not available in GLSL. Until that is done, we can work around it in bevy using a push constant which is converted to a uniform by naga and wgpu. # Objective - Fixes #9375 ## Solution - Use a push constant to pass in the base instance to the shader on WebGL2 so that base instance + gl_InstanceID is used to correctly represent the instance index. ## TODO - [ ] Benchmark vs per-object dynamic offset MeshUniform as this will now push a uniform value per-draw as well as update the dynamic offset per-batch. - [x] Test on DX12 AMD/NVIDIA to check that this PR does not regress any problems that were observed there. (@Elabajaba @robtfm were testing that last time - help appreciated. <3 ) --- ## Changelog - Added: `bevy_render::instance_index` shader import which includes a workaround for the lack of a WGSL `instance_index` polyfill for WebGL2 in naga and wgpu for the time being. It uses a push_constant which gets converted to a plain uniform by naga and wgpu. ## Migration Guide Shader code before: ``` struct Vertex { @builtin(instance_index) instance_index: u32, ... } @vertex fn vertex(vertex_no_morph: Vertex) -> VertexOutput { ... var model = mesh[vertex_no_morph.instance_index].model; ``` After: ``` #import bevy_render::instance_index struct Vertex { @builtin(instance_index) instance_index: u32, ... } @vertex fn vertex(vertex_no_morph: Vertex) -> VertexOutput { ... var model = mesh[bevy_render::instance_index::get_instance_index(vertex_no_morph.instance_index)].model; ```
2023-08-09 18:38:45 +00:00
#define_import_path bevy_render::instance_index
#ifdef BASE_INSTANCE_WORKAROUND
// naga and wgpu should polyfill WGSL instance_index functionality where it is
// not available in GLSL. Until that is done, we can work around it in bevy
// using a push constant which is converted to a uniform by naga and wgpu.
// https://github.com/gfx-rs/wgpu/issues/1573
var<push_constant> base_instance: i32;
fn get_instance_index(instance_index: u32) -> u32 {
return u32(base_instance) + instance_index;
}
#else
fn get_instance_index(instance_index: u32) -> u32 {
return instance_index;
}
#endif