Skip to content

Commit 2f80d08

Browse files
authored
Fix many_foxes + motion blur = crash on WebGL (#18715)
## Objective Fix #18714. ## Solution Make sure `SkinUniforms::prev_buffer` is resized at the same time as `current_buffer`. There will be a one frame visual glitch when the buffers are resized, since `prev_buffer` is incorrectly initialised with the current joint transforms. Note that #18074 includes the same fix. I'm assuming this smaller PR will land first. ## Testing See repro instructions in #18714. Tested on `animated_mesh`, `many_foxes`, `custom_skinned_mesh`, Win10/Nvidia with Vulkan, WebGL/Chrome, WebGPU/Chrome.
1 parent d82c359 commit 2f80d08

File tree

1 file changed

+20
-2
lines changed

1 file changed

+20
-2
lines changed

crates/bevy_pbr/src/render/skin.rs

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ pub fn prepare_skins(
211211
// Swap current and previous buffers.
212212
mem::swap(&mut uniform.current_buffer, &mut uniform.prev_buffer);
213213

214-
// Resize the buffer if necessary. Include extra space equal to `MAX_JOINTS`
214+
// Resize the buffers if necessary. Include extra space equal to `MAX_JOINTS`
215215
// because we need to be able to bind a full uniform buffer's worth of data
216216
// if skins use uniform buffers on this platform.
217217
let needed_size = (uniform.current_staging_buffer.len() as u64 + MAX_JOINTS as u64)
@@ -223,7 +223,7 @@ pub fn prepare_skins(
223223
new_size += new_size / 2;
224224
}
225225

226-
// Create a new buffer.
226+
// Create the new buffers.
227227
let buffer_usages = if skins_use_uniform_buffers(&render_device) {
228228
BufferUsages::UNIFORM
229229
} else {
@@ -235,6 +235,24 @@ pub fn prepare_skins(
235235
size: new_size,
236236
mapped_at_creation: false,
237237
});
238+
uniform.prev_buffer = render_device.create_buffer(&BufferDescriptor {
239+
label: Some("skin uniform buffer"),
240+
usage: buffer_usages,
241+
size: new_size,
242+
mapped_at_creation: false,
243+
});
244+
245+
// We've created a new `prev_buffer` but we don't have the previous joint
246+
// data needed to fill it out correctly. Use the current joint data
247+
// instead.
248+
//
249+
// TODO: This is a bug - will cause motion blur to ignore joint movement
250+
// for one frame.
251+
render_queue.write_buffer(
252+
&uniform.prev_buffer,
253+
0,
254+
bytemuck::must_cast_slice(&uniform.current_staging_buffer[..]),
255+
);
238256
}
239257

240258
// Write the data from `uniform.current_staging_buffer` into

0 commit comments

Comments
 (0)