bevy/assets/shaders/bindless_material.wgsl
Patrick Walton 35826be6f7
Implement bindless lightmaps. (#16653)
This commit allows Bevy to bind 16 lightmaps at a time, if the current
platform supports bindless textures. Naturally, if bindless textures
aren't supported, Bevy falls back to binding only a single lightmap at a
time. As lightmaps are usually heavily atlased, I doubt many scenes will
use more than 16 lightmap textures.

This has little performance impact now, but it's desirable for us to
reap the benefits of multidraw and bindless textures on scenes that use
lightmaps. Otherwise, we might have to break batches in order to switch
those lightmaps.

Additionally, this PR slightly reduces the cost of binning because it
makes the lightmap index in `Opaque3dBinKey` 32 bits instead of an
`AssetId`.

## Migration Guide

* The `Opaque3dBinKey::lightmap_image` field is now
`Opaque3dBinKey::lightmap_slab`, which is a lightweight identifier for
an entire binding array of lightmaps.
2024-12-16 23:37:06 +00:00

39 lines
1.2 KiB
WebGPU Shading Language

#import bevy_pbr::forward_io::VertexOutput
#import bevy_pbr::mesh_bindings::mesh
struct Color {
base_color: vec4<f32>,
}
#ifdef BINDLESS
@group(2) @binding(0) var<storage> material_color: binding_array<Color, 4>;
@group(2) @binding(1) var material_color_texture: binding_array<texture_2d<f32>, 4>;
@group(2) @binding(2) var material_color_sampler: binding_array<sampler, 4>;
#else // BINDLESS
@group(2) @binding(0) var<uniform> material_color: Color;
@group(2) @binding(1) var material_color_texture: texture_2d<f32>;
@group(2) @binding(2) var material_color_sampler: sampler;
#endif // BINDLESS
@fragment
fn fragment(in: VertexOutput) -> @location(0) vec4<f32> {
#ifdef BINDLESS
let slot = mesh[in.instance_index].material_and_lightmap_bind_group_slot & 0xffffu;
let base_color = material_color[slot].base_color;
#else // BINDLESS
let base_color = material_color.base_color;
#endif // BINDLESS
return base_color * textureSampleLevel(
#ifdef BINDLESS
material_color_texture[slot],
material_color_sampler[slot],
#else // BINDLESS
material_color_texture,
material_color_sampler,
#endif // BINDLESS
in.uv,
0.0
);
}