Fix motion blur on skinned meshes (#18712)
## Objective Fix motion blur not working on skinned meshes. ## Solution `set_mesh_motion_vector_flags` can set `RenderMeshInstanceFlags::HAS_PREVIOUS_SKIN` after specialization has already cached the material. This can lead to `MeshPipelineKey::HAS_PREVIOUS_SKIN` never getting set, disabling motion blur. The fix is to make sure `set_mesh_motion_vector_flags` happens before specialization. Note that the bug is fixed in a different way by #18074, which includes other fixes but is a much larger change. ## Testing Open the `animated_mesh` example and add these components to the `Camera3d` entity: ```rust MotionBlur { shutter_angle: 5.0, samples: 2, #[cfg(all(feature = "webgl2", target_arch = "wasm32", not(feature = "webgpu")))] _webgl2_padding: Default::default(), }, #[cfg(all(feature = "webgl2", target_arch = "wasm32", not(feature = "webgpu")))] Msaa::Off, ``` Tested on `animated_mesh`, `many_foxes`, `custom_skinned_mesh`, Win10/Nvidia with Vulkan, WebGL/Chrome, WebGPU/Chrome. Note that testing `many_foxes` WebGL requires #18715.
This commit is contained in:
parent
78d5c50b50
commit
5da64ddbee
@ -327,7 +327,8 @@ where
|
||||
.in_set(RenderSet::PrepareMeshes)
|
||||
.after(prepare_assets::<PreparedMaterial<M>>)
|
||||
.after(prepare_assets::<RenderMesh>)
|
||||
.after(collect_meshes_for_gpu_building),
|
||||
.after(collect_meshes_for_gpu_building)
|
||||
.after(set_mesh_motion_vector_flags),
|
||||
queue_material_meshes::<M>
|
||||
.in_set(RenderSet::QueueMeshes)
|
||||
.after(prepare_assets::<PreparedMaterial<M>>),
|
||||
|
@ -3,11 +3,11 @@ mod prepass_bindings;
|
||||
use crate::{
|
||||
alpha_mode_pipeline_key, binding_arrays_are_usable, buffer_layout,
|
||||
collect_meshes_for_gpu_building, material_bind_groups::MaterialBindGroupAllocator,
|
||||
queue_material_meshes, setup_morph_and_skinning_defs, skin, DrawMesh,
|
||||
EntitySpecializationTicks, Material, MaterialPipeline, MaterialPipelineKey, MeshLayouts,
|
||||
MeshPipeline, MeshPipelineKey, OpaqueRendererMethod, PreparedMaterial, RenderLightmaps,
|
||||
RenderMaterialInstances, RenderMeshInstanceFlags, RenderMeshInstances, RenderPhaseType,
|
||||
SetMaterialBindGroup, SetMeshBindGroup, ShadowView, StandardMaterial,
|
||||
queue_material_meshes, set_mesh_motion_vector_flags, setup_morph_and_skinning_defs, skin,
|
||||
DrawMesh, EntitySpecializationTicks, Material, MaterialPipeline, MaterialPipelineKey,
|
||||
MeshLayouts, MeshPipeline, MeshPipelineKey, OpaqueRendererMethod, PreparedMaterial,
|
||||
RenderLightmaps, RenderMaterialInstances, RenderMeshInstanceFlags, RenderMeshInstances,
|
||||
RenderPhaseType, SetMaterialBindGroup, SetMeshBindGroup, ShadowView, StandardMaterial,
|
||||
};
|
||||
use bevy_app::{App, Plugin, PreUpdate};
|
||||
use bevy_render::{
|
||||
@ -219,7 +219,8 @@ where
|
||||
.in_set(RenderSet::PrepareMeshes)
|
||||
.after(prepare_assets::<PreparedMaterial<M>>)
|
||||
.after(prepare_assets::<RenderMesh>)
|
||||
.after(collect_meshes_for_gpu_building),
|
||||
.after(collect_meshes_for_gpu_building)
|
||||
.after(set_mesh_motion_vector_flags),
|
||||
queue_prepass_material_meshes::<M>
|
||||
.in_set(RenderSet::QueueMeshes)
|
||||
.after(prepare_assets::<PreparedMaterial<M>>)
|
||||
|
@ -1648,7 +1648,7 @@ fn extract_mesh_for_gpu_building(
|
||||
/// [`crate::material::queue_material_meshes`] check the skin and morph target
|
||||
/// tables for each mesh, but that would be too slow in the hot mesh queuing
|
||||
/// loop.
|
||||
fn set_mesh_motion_vector_flags(
|
||||
pub(crate) fn set_mesh_motion_vector_flags(
|
||||
mut render_mesh_instances: ResMut<RenderMeshInstances>,
|
||||
skin_uniforms: Res<SkinUniforms>,
|
||||
morph_indices: Res<MorphIndices>,
|
||||
|
Loading…
Reference in New Issue
Block a user