Search across packages, versions, files, declarations, and comments. Use multiple terms to narrow results (AND), and add @vertex, @fragment, or @compute to filter by shader stage.
1import bevy_pbr::render::{forward_io::VertexOutput, mesh_bindings::mesh};
2import bevy_render::bindless::{bindless_samplers_filtering, bindless_textures_2d};
4/// The custom data that we extract from the ECS and expose to this shader.
5struct CustomMaterialData {
6 /// The tint color for the mesh.
7 color: vec3<f32>,
8 /// Padding to pad this out to a multiple of 16 bytes.
9 pad: u32,
12/// The array of material data that Bevy supplies.
13///
14/// We need to declare this type because
15/// `binding_array<array<CustomMaterialData>>` isn't currently accepted by Naga.
16/// We have to factor the `array<CustomMaterialData>` out into a separate type.
17struct CustomMaterialDataArray {
18 data_array: array<CustomMaterialData>,
21@if(BINDLESS) {
23/// The bindings table for bindless mode.
24///
25/// These are indexes into the various arrays.
26struct CustomMaterialBindings {
27 material: u32, // 0
28 /// The index of the data for this instance in the `CustomMaterialDataArray`.
29 data: u32, // 1
30 /// The index of the color texture for this instance in the
31 /// `bindless_textures_2d`.
32 color_texture: u32, // 2
33 /// The index of the sampler for this instance in the
34 /// `bindless_samplers_filtering`.
35 color_texture_sampler: u32, // 3
38@group(constants::MATERIAL_BIND_GROUP) @binding(0) var<storage> material_indices:
39 array<CustomMaterialBindings>;
40@group(constants::MATERIAL_BIND_GROUP) @binding(4) var<storage> material_data:
41 binding_array<CustomMaterialDataArray>;
43} @else {
45@group(constants::MATERIAL_BIND_GROUP) @binding(1) var<storage> material_data: CustomMaterialDataArray;
46@group(constants::MATERIAL_BIND_GROUP) @binding(2) var color_texture: texture_2d<f32>;
47@group(constants::MATERIAL_BIND_GROUP) @binding(3) var color_texture_sampler: sampler;
51@fragment
52fn fragment(in: VertexOutput) -> @location(0) vec4<f32> {
53 // The tag stores the index of the data in the data array.
54 let tag = mesh[in.instance_index].tag;
56@if(BINDLESS) {
58 // Look up the bindless slot for this mesh.
59 let slot = mesh[in.instance_index].material_and_lightmap_bind_group_slot & 0xffffu;
61 // Unpack the bindless indices.
62 let data_index = material_indices[slot].data;
63 let color_texture_index = material_indices[slot].color_texture;
64 let color_texture_sampler_index = material_indices[slot].color_texture_sampler;
66 // Grab the color from the material data array.
67 //
68 // Note that there are two levels of arrays here: the binding array and the
69 // data array. The binding array should only have one element in this case,
70 // but Bevy still supplies a binding array because it's legal for different
71 // materials to have different `ShaderBuffer` bindings, even though in our
72 // case all materials are bound to the same buffer. The data array contains
73 // all of the instance data and is indexed by the tag.
74 let color = material_data[data_index].data_array[tag].color;
76 // Sample from the appropriate texture in the bindless textures array.
77 let texture_color = textureSample(
78 bindless_textures_2d[color_texture_index],
79 bindless_samplers_filtering[color_texture_sampler_index],
80 in.uv
81 ).rgb;
83} @else {
85 // In non-bindless mode, we only have one buffer, so we simply use the tag
86 // as an index into the array.
87 let color = material_data.data_array[tag].color;
89 let texture_color = textureSample(color_texture, color_texture_sampler, in.uv).rgb;
93 // Modulate the texture by the appropriate tint color.
94 return vec4<f32>(color * texture_color, 1.0);
Contents