Fix: Provide CPU mesh processing with MaterialBindingId (#19083)

# Objective
Fixes #19027

## Solution
Query for the material binding id if using fallback CPU processing

## Testing
I've honestly no clue how to test for this, and I imagine that this
isn't entirely failsafe :( but would highly appreciate a suggestion!

To verify this works, please run the the texture.rs example using WebGL
2.

Additionally, I'm extremely naive about the nuances of pbr. This PR is
essentially to kinda *get the ball rolling* of sorts. Thanks :)

---------

Co-authored-by: Gilles Henaux <ghx_github_priv@fastmail.com>
Co-authored-by: charlotte <charlotte.c.mcelwain@gmail.com>
This commit is contained in:
Daniel Gallups 2025-05-12 14:11:14 -04:00 committed by François Mockers
parent 6826676e41
commit efde13a827

View File

@ -837,12 +837,33 @@ pub struct RenderMeshInstanceGpuQueues(Parallel<RenderMeshInstanceGpuQueue>);
pub struct MeshesToReextractNextFrame(MainEntityHashSet);
impl RenderMeshInstanceShared {
fn from_components(
/// A gpu builder will provide the mesh instance id
/// during [`RenderMeshInstanceGpuBuilder::update`].
fn for_gpu_building(
previous_transform: Option<&PreviousGlobalTransform>,
mesh: &Mesh3d,
tag: Option<&MeshTag>,
not_shadow_caster: bool,
no_automatic_batching: bool,
) -> Self {
Self::for_cpu_building(
previous_transform,
mesh,
tag,
default(),
not_shadow_caster,
no_automatic_batching,
)
}
/// The cpu builder does not have an equivalent [`RenderMeshInstanceGpuBuilder::update`].
fn for_cpu_building(
previous_transform: Option<&PreviousGlobalTransform>,
mesh: &Mesh3d,
tag: Option<&MeshTag>,
material_bindings_index: MaterialBindingId,
not_shadow_caster: bool,
no_automatic_batching: bool,
) -> Self {
let mut mesh_instance_flags = RenderMeshInstanceFlags::empty();
mesh_instance_flags.set(RenderMeshInstanceFlags::SHADOW_CASTER, !not_shadow_caster);
@ -858,8 +879,7 @@ impl RenderMeshInstanceShared {
RenderMeshInstanceShared {
mesh_asset_id: mesh.id(),
flags: mesh_instance_flags,
// This gets filled in later, during `RenderMeshGpuBuilder::update`.
material_bindings_index: default(),
material_bindings_index,
lightmap_slab_index: None,
tag: tag.map_or(0, |i| **i),
}
@ -1305,6 +1325,8 @@ pub struct ExtractMeshesSet;
/// [`MeshUniform`] building.
pub fn extract_meshes_for_cpu_building(
mut render_mesh_instances: ResMut<RenderMeshInstances>,
mesh_material_ids: Res<RenderMaterialInstances>,
render_material_bindings: Res<RenderMaterialBindings>,
render_visibility_ranges: Res<RenderVisibilityRanges>,
mut render_mesh_instance_queues: Local<Parallel<Vec<(Entity, RenderMeshInstanceCpu)>>>,
meshes_query: Extract<
@ -1358,10 +1380,18 @@ pub fn extract_meshes_for_cpu_building(
transmitted_receiver,
);
let shared = RenderMeshInstanceShared::from_components(
let mesh_material = mesh_material_ids.mesh_material(MainEntity::from(entity));
let material_bindings_index = render_material_bindings
.get(&mesh_material)
.copied()
.unwrap_or_default();
let shared = RenderMeshInstanceShared::for_cpu_building(
previous_transform,
mesh,
tag,
material_bindings_index,
not_shadow_caster,
no_automatic_batching,
);
@ -1566,7 +1596,7 @@ fn extract_mesh_for_gpu_building(
transmitted_receiver,
);
let shared = RenderMeshInstanceShared::from_components(
let shared = RenderMeshInstanceShared::for_gpu_building(
previous_transform,
mesh,
tag,