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.
This commit is contained in:
parent
d82c359a5a
commit
2f80d081bc
@ -211,7 +211,7 @@ pub fn prepare_skins(
|
|||||||
// Swap current and previous buffers.
|
// Swap current and previous buffers.
|
||||||
mem::swap(&mut uniform.current_buffer, &mut uniform.prev_buffer);
|
mem::swap(&mut uniform.current_buffer, &mut uniform.prev_buffer);
|
||||||
|
|
||||||
// Resize the buffer if necessary. Include extra space equal to `MAX_JOINTS`
|
// Resize the buffers if necessary. Include extra space equal to `MAX_JOINTS`
|
||||||
// because we need to be able to bind a full uniform buffer's worth of data
|
// because we need to be able to bind a full uniform buffer's worth of data
|
||||||
// if skins use uniform buffers on this platform.
|
// if skins use uniform buffers on this platform.
|
||||||
let needed_size = (uniform.current_staging_buffer.len() as u64 + MAX_JOINTS as u64)
|
let needed_size = (uniform.current_staging_buffer.len() as u64 + MAX_JOINTS as u64)
|
||||||
@ -223,7 +223,7 @@ pub fn prepare_skins(
|
|||||||
new_size += new_size / 2;
|
new_size += new_size / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a new buffer.
|
// Create the new buffers.
|
||||||
let buffer_usages = if skins_use_uniform_buffers(&render_device) {
|
let buffer_usages = if skins_use_uniform_buffers(&render_device) {
|
||||||
BufferUsages::UNIFORM
|
BufferUsages::UNIFORM
|
||||||
} else {
|
} else {
|
||||||
@ -235,6 +235,24 @@ pub fn prepare_skins(
|
|||||||
size: new_size,
|
size: new_size,
|
||||||
mapped_at_creation: false,
|
mapped_at_creation: false,
|
||||||
});
|
});
|
||||||
|
uniform.prev_buffer = render_device.create_buffer(&BufferDescriptor {
|
||||||
|
label: Some("skin uniform buffer"),
|
||||||
|
usage: buffer_usages,
|
||||||
|
size: new_size,
|
||||||
|
mapped_at_creation: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
// We've created a new `prev_buffer` but we don't have the previous joint
|
||||||
|
// data needed to fill it out correctly. Use the current joint data
|
||||||
|
// instead.
|
||||||
|
//
|
||||||
|
// TODO: This is a bug - will cause motion blur to ignore joint movement
|
||||||
|
// for one frame.
|
||||||
|
render_queue.write_buffer(
|
||||||
|
&uniform.prev_buffer,
|
||||||
|
0,
|
||||||
|
bytemuck::must_cast_slice(&uniform.current_staging_buffer[..]),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write the data from `uniform.current_staging_buffer` into
|
// Write the data from `uniform.current_staging_buffer` into
|
||||||
|
Loading…
Reference in New Issue
Block a user