Skip to content

Commit 3c6fad2

Browse files
authored
Fix shader_material_glsl example after #9254 (#9311)
# Objective - Fix shader_material_glsl example ## Solution - Expose the `PER_OBJECT_BUFFER_BATCH_SIZE` shader def through the default `MeshPipeline` specialization. - Make use of it in the `custom_material.vert` shader to access the mesh binding. --- ## Changelog - Added: Exposed the `PER_OBJECT_BUFFER_BATCH_SIZE` shader def through the default `MeshPipeline` specialization to use in custom shaders not using bevy_pbr::mesh_bindings that still want to use the mesh binding in some way.
1 parent 08ea1d1 commit 3c6fad2

File tree

2 files changed

+37
-2
lines changed

2 files changed

+37
-2
lines changed

assets/shaders/custom_material.vert

+12-2
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,23 @@ layout(set = 0, binding = 0) uniform CameraViewProj {
1616
float height;
1717
};
1818

19-
layout(set = 2, binding = 0) uniform Mesh {
19+
struct Mesh {
2020
mat4 Model;
2121
mat4 InverseTransposeModel;
2222
uint flags;
2323
};
2424

25+
#ifdef PER_OBJECT_BUFFER_BATCH_SIZE
26+
layout(set = 2, binding = 0) uniform Mesh Meshes[#{PER_OBJECT_BUFFER_BATCH_SIZE}];
27+
#else
28+
layout(set = 2, binding = 0) readonly buffer _Meshes {
29+
Mesh Meshes[];
30+
};
31+
#endif // PER_OBJECT_BUFFER_BATCH_SIZE
32+
2533
void main() {
2634
v_Uv = Vertex_Uv;
27-
gl_Position = ViewProj * Model * vec4(Vertex_Position, 1.0);
35+
gl_Position = ViewProj
36+
* Meshes[gl_BaseInstance + gl_InstanceIndex].Model
37+
* vec4(Vertex_Position, 1.0);
2838
}

crates/bevy_pbr/src/render/mesh.rs

+25
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,20 @@ pub struct MeshPipeline {
325325
pub dummy_white_gpu_image: GpuImage,
326326
pub clustered_forward_buffer_binding_type: BufferBindingType,
327327
pub mesh_layouts: MeshLayouts,
328+
/// `MeshUniform`s are stored in arrays in buffers. If storage buffers are available, they
329+
/// are used and this will be `None`, otherwise uniform buffers will be used with batches
330+
/// of this many `MeshUniform`s, stored at dynamic offsets within the uniform buffer.
331+
/// Use code like this in custom shaders:
332+
/// ```wgsl
333+
/// ##ifdef PER_OBJECT_BUFFER_BATCH_SIZE
334+
/// @group(2) @binding(0)
335+
/// var<uniform> mesh: array<Mesh, #{PER_OBJECT_BUFFER_BATCH_SIZE}u>;
336+
/// ##else
337+
/// @group(2) @binding(0)
338+
/// var<storage> mesh: array<Mesh>;
339+
/// ##endif // PER_OBJECT_BUFFER_BATCH_SIZE
340+
/// ```
341+
pub per_object_buffer_batch_size: Option<u32>,
328342
}
329343

330344
impl FromWorld for MeshPipeline {
@@ -564,6 +578,7 @@ impl FromWorld for MeshPipeline {
564578
clustered_forward_buffer_binding_type,
565579
dummy_white_gpu_image,
566580
mesh_layouts: MeshLayouts::new(&render_device),
581+
per_object_buffer_batch_size: GpuArrayBuffer::<MeshUniform>::batch_size(&render_device),
567582
}
568583
}
569584
}
@@ -866,6 +881,16 @@ impl SpecializedMeshPipeline for MeshPipeline {
866881
TextureFormat::bevy_default()
867882
};
868883

884+
// This is defined here so that custom shaders that use something other than
885+
// the mesh binding from bevy_pbr::mesh_bindings can easily make use of this
886+
// in their own shaders.
887+
if let Some(per_object_buffer_batch_size) = self.per_object_buffer_batch_size {
888+
shader_defs.push(ShaderDefVal::UInt(
889+
"PER_OBJECT_BUFFER_BATCH_SIZE".into(),
890+
per_object_buffer_batch_size,
891+
));
892+
}
893+
869894
Ok(RenderPipelineDescriptor {
870895
vertex: VertexState {
871896
shader: MESH_SHADER_HANDLE.typed::<Shader>(),

0 commit comments

Comments
 (0)