Skip to content

Commit 9bf8c5b

Browse files
committed
HACK: Split batches for skinning or morph targets
1 parent 29b8a29 commit 9bf8c5b

File tree

3 files changed

+25
-9
lines changed

3 files changed

+25
-9
lines changed

crates/bevy_pbr/src/material.rs

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::{
2-
render, AlphaMode, DrawMesh, DrawPrepass, EnvironmentMapLight, MeshPipeline, MeshPipelineKey,
3-
MeshTransforms, PrepassPipelinePlugin, PrepassPlugin, ScreenSpaceAmbientOcclusionSettings,
4-
SetMeshBindGroup, SetMeshViewBindGroup, Shadow,
2+
is_skinned, render, AlphaMode, DrawMesh, DrawPrepass, EnvironmentMapLight, MeshFlags,
3+
MeshPipeline, MeshPipelineKey, MeshTransforms, PrepassPipelinePlugin, PrepassPlugin,
4+
ScreenSpaceAmbientOcclusionSettings, SetMeshBindGroup, SetMeshViewBindGroup, Shadow,
55
};
66
use bevy_app::{App, Plugin};
77
use bevy_asset::{AddAsset, AssetEvent, AssetServer, Assets, Handle};
@@ -409,7 +409,7 @@ pub fn queue_material_meshes<M: Material>(
409409
&Handle<M>,
410410
&mut MaterialBindGroupId,
411411
&Handle<Mesh>,
412-
&MeshTransforms,
412+
&mut MeshTransforms,
413413
)>,
414414
images: Res<RenderAssets<Image>>,
415415
mut views: Query<(
@@ -494,8 +494,12 @@ pub fn queue_material_meshes<M: Material>(
494494

495495
let rangefinder = view.rangefinder3d();
496496
for visible_entity in &visible_entities.entities {
497-
if let Ok((material_handle, mut material_bind_group_id, mesh_handle, mesh_transforms)) =
498-
material_meshes.get_mut(*visible_entity)
497+
if let Ok((
498+
material_handle,
499+
mut material_bind_group_id,
500+
mesh_handle,
501+
mut mesh_transforms,
502+
)) = material_meshes.get_mut(*visible_entity)
499503
{
500504
if let (Some(mesh), Some(material)) = (
501505
render_meshes.get(mesh_handle),
@@ -504,8 +508,13 @@ pub fn queue_material_meshes<M: Material>(
504508
let mut mesh_key =
505509
MeshPipelineKey::from_primitive_topology(mesh.primitive_topology)
506510
| view_key;
511+
512+
if is_skinned(&mesh.layout) {
513+
mesh_transforms.flags |= MeshFlags::SKINNED.bits();
514+
}
507515
if mesh.morph_targets.is_some() {
508516
mesh_key |= MeshPipelineKey::MORPH_TARGETS;
517+
mesh_transforms.flags |= MeshFlags::MORPH_TARGETS.bits();
509518
}
510519
match material.properties.alpha_mode {
511520
AlphaMode::Blend => {

crates/bevy_pbr/src/render/mesh.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -247,8 +247,10 @@ impl From<&MeshTransforms> for MeshUniform {
247247
// NOTE: These must match the bit flags in bevy_pbr/src/render/mesh_types.wgsl!
248248
bitflags::bitflags! {
249249
#[repr(transparent)]
250-
struct MeshFlags: u32 {
250+
pub struct MeshFlags: u32 {
251251
const SHADOW_RECEIVER = (1 << 0);
252+
const SKINNED = (1 << 1);
253+
const MORPH_TARGETS = (1 << 2);
252254
// Indicates the sign of the determinant of the 3x3 model matrix. If the sign is positive,
253255
// then the flag should be set, else it should not be set.
254256
const SIGN_DETERMINANT_MODEL_3X3 = (1 << 31);
@@ -413,6 +415,7 @@ struct BatchMeta<'mat, 'mesh> {
413415
/// dynamic offsets.
414416
material_binding_meta: Option<&'mat MaterialBindGroupId>,
415417
mesh_handle: Option<&'mesh Handle<Mesh>>,
418+
mesh_flags: u32,
416419
dynamic_offset: Option<NonMaxU32>,
417420
}
418421

@@ -422,6 +425,7 @@ impl<'mat, 'mesh> BatchMeta<'mat, 'mesh> {
422425
self.pipeline_id == other.pipeline_id
423426
&& self.draw_function_id == other.draw_function_id
424427
&& self.mesh_handle == other.mesh_handle
428+
&& (self.mesh_flags & (MeshFlags::SKINNED | MeshFlags::MORPH_TARGETS).bits()) == 0
425429
&& self.dynamic_offset == other.dynamic_offset
426430
&& (!consider_material || self.material_binding_meta == other.material_binding_meta)
427431
}
@@ -470,6 +474,7 @@ fn process_phase<I: CachedRenderPipelinePhaseItem>(
470474
draw_function_id: Some(item.draw_function()),
471475
material_binding_meta,
472476
mesh_handle: Some(mesh_handle),
477+
mesh_flags: mesh_transforms.flags,
473478
dynamic_offset: gpu_array_buffer_index.dynamic_offset,
474479
};
475480
if !batch_meta.matches(&batch.meta, consider_material) {
@@ -939,7 +944,7 @@ impl MeshPipelineKey {
939944
}
940945
}
941946

942-
fn is_skinned(layout: &Hashed<InnerMeshVertexBufferLayout>) -> bool {
947+
pub fn is_skinned(layout: &Hashed<InnerMeshVertexBufferLayout>) -> bool {
943948
layout.contains(Mesh::ATTRIBUTE_JOINT_INDEX) && layout.contains(Mesh::ATTRIBUTE_JOINT_WEIGHT)
944949
}
945950
pub fn setup_morph_and_skinning_defs(

crates/bevy_pbr/src/render/mesh_types.wgsl

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ struct MorphWeights {
2828
};
2929
#endif
3030

31-
const MESH_FLAGS_SHADOW_RECEIVER_BIT: u32 = 1u;
31+
const MESH_FLAGS_SHADOW_RECEIVER_BIT: u32 = 1u;
32+
const MESH_FLAGS_SKINNED_BIT: u32 = 2u;
33+
const MESH_FLAGS_MORPH_TARGETS_BIT: u32 = 4u;
3234
// 2^31 - if the flag is set, the sign is positive, else it is negative
3335
const MESH_FLAGS_SIGN_DETERMINANT_MODEL_3X3_BIT: u32 = 2147483648u;

0 commit comments

Comments
 (0)