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.
This commit is contained in:
Robert Swain 2023-07-31 15:14:40 +02:00 committed by GitHub
parent 08ea1d18ae
commit 3c6fad269b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 37 additions and 2 deletions

View file

@ -16,13 +16,23 @@ layout(set = 0, binding = 0) uniform CameraViewProj {
float height; float height;
}; };
layout(set = 2, binding = 0) uniform Mesh { struct Mesh {
mat4 Model; mat4 Model;
mat4 InverseTransposeModel; mat4 InverseTransposeModel;
uint flags; uint flags;
}; };
#ifdef PER_OBJECT_BUFFER_BATCH_SIZE
layout(set = 2, binding = 0) uniform Mesh Meshes[#{PER_OBJECT_BUFFER_BATCH_SIZE}];
#else
layout(set = 2, binding = 0) readonly buffer _Meshes {
Mesh Meshes[];
};
#endif // PER_OBJECT_BUFFER_BATCH_SIZE
void main() { void main() {
v_Uv = Vertex_Uv; v_Uv = Vertex_Uv;
gl_Position = ViewProj * Model * vec4(Vertex_Position, 1.0); gl_Position = ViewProj
* Meshes[gl_BaseInstance + gl_InstanceIndex].Model
* vec4(Vertex_Position, 1.0);
} }

View file

@ -325,6 +325,20 @@ pub struct MeshPipeline {
pub dummy_white_gpu_image: GpuImage, pub dummy_white_gpu_image: GpuImage,
pub clustered_forward_buffer_binding_type: BufferBindingType, pub clustered_forward_buffer_binding_type: BufferBindingType,
pub mesh_layouts: MeshLayouts, pub mesh_layouts: MeshLayouts,
/// `MeshUniform`s are stored in arrays in buffers. If storage buffers are available, they
/// are used and this will be `None`, otherwise uniform buffers will be used with batches
/// of this many `MeshUniform`s, stored at dynamic offsets within the uniform buffer.
/// Use code like this in custom shaders:
/// ```wgsl
/// ##ifdef PER_OBJECT_BUFFER_BATCH_SIZE
/// @group(2) @binding(0)
/// var<uniform> mesh: array<Mesh, #{PER_OBJECT_BUFFER_BATCH_SIZE}u>;
/// ##else
/// @group(2) @binding(0)
/// var<storage> mesh: array<Mesh>;
/// ##endif // PER_OBJECT_BUFFER_BATCH_SIZE
/// ```
pub per_object_buffer_batch_size: Option<u32>,
} }
impl FromWorld for MeshPipeline { impl FromWorld for MeshPipeline {
@ -564,6 +578,7 @@ impl FromWorld for MeshPipeline {
clustered_forward_buffer_binding_type, clustered_forward_buffer_binding_type,
dummy_white_gpu_image, dummy_white_gpu_image,
mesh_layouts: MeshLayouts::new(&render_device), mesh_layouts: MeshLayouts::new(&render_device),
per_object_buffer_batch_size: GpuArrayBuffer::<MeshUniform>::batch_size(&render_device),
} }
} }
} }
@ -866,6 +881,16 @@ impl SpecializedMeshPipeline for MeshPipeline {
TextureFormat::bevy_default() TextureFormat::bevy_default()
}; };
// This is defined here so that custom shaders that use something other than
// the mesh binding from bevy_pbr::mesh_bindings can easily make use of this
// in their own shaders.
if let Some(per_object_buffer_batch_size) = self.per_object_buffer_batch_size {
shader_defs.push(ShaderDefVal::UInt(
"PER_OBJECT_BUFFER_BATCH_SIZE".into(),
per_object_buffer_batch_size,
));
}
Ok(RenderPipelineDescriptor { Ok(RenderPipelineDescriptor {
vertex: VertexState { vertex: VertexState {
shader: MESH_SHADER_HANDLE.typed::<Shader>(), shader: MESH_SHADER_HANDLE.typed::<Shader>(),