-
-
Notifications
You must be signed in to change notification settings - Fork 4.3k
Closed
Labels
A-RenderingDrawing game state to the screenDrawing game state to the screenC-BugAn unexpected or incorrect behaviorAn unexpected or incorrect behaviorS-Ready-For-ImplementationThis issue is ready for an implementation PR. Go for it!This issue is ready for an implementation PR. Go for it!
Description
Bevy version
0.8
[Optional] Relevant system information
2022-08-06T16:11:23.218862Z INFO bevy_render::renderer: AdapterInfo { name: "Apple M1", vendor: 0, device: 0, device_type: IntegratedGpu, backend: Metal }
What you did
- Used post_processing as an example, made my main camera output to an
Imagetarget. - Subscribed to window resize events.
- Updated camera target image descriptor size and size.
What went wrong
Panic due to validation error.
2022-08-06T16:14:40.407438Z ERROR wgpu::backend::direct: Handling wgpu errors as fatal by default
thread 'main' panicked at 'wgpu error: Validation Error
Caused by:
In a RenderPass
note: encoder = `<CommandBuffer-(0, 8478, Metal)>`
In a pass parameter
note: command buffer = `<CommandBuffer-(0, 8478, Metal)>`
attachments have differing sizes: ("color", Extent3d { width: 800, height: 800, depth_or_array_layers: 1 }) is followed by ("resolve", Extent3d { width: 798, height: 780, depth_or_array_layers: 1 })
Additional information
Resizing code that causes error:
fn update_target_on_resize(
....
mut events: EventReader<WindowResized>,
mut query_camera: Query<(Entity, &Camera, &CameraVelocity, &Transform, &OrthographicProjection), With<CameraMain>>,
) {
// Take the last resize event.
let mut window_resized = None;
for event in events.iter() {
window_resized = Some(event);
}
if let Some(event) = window_resized {
if let Ok(post_processing_material_handle) = query_handle.get_single() {
if let Some(post_processing_material) = materials.get_mut(&post_processing_material_handle.handle) {
if let Some(camera_target) = images.get_mut(&post_processing_material.source_image) {
// TODO: use physical dimensions.
let size = Extent3d{
width: event.width as u32,
height: event.height as u32,
..default()
};
camera_target.texture_descriptor.size = size;
camera_target.resize(camera_target.texture_descriptor.size);
Workaround with despawning main camera:
fn update_target_on_resize(
mut commands: Commands,
mut events: EventReader<WindowResized>,
query_handle: Query<&PostProcessingHandle>,
config: Res<MainCameraConfig>,
mut materials: ResMut<Assets<PostProcessingMaterial>>,
mut images: ResMut<Assets<Image>>,
mut query_camera: Query<(Entity, &Camera, &CameraVelocity, &Transform, &OrthographicProjection), With<CameraMain>>,
) {
// Take the last resize event.
let mut window_resized = None;
for event in events.iter() {
window_resized = Some(event);
}
// Resize image for post-processing material and re-spawn main camera.
if let Some(event) = window_resized {
if let Ok(post_processing_material_handle) = query_handle.get_single() {
if let Some(post_processing_material) = materials.get_mut(&post_processing_material_handle.handle) {
if let Some(camera_target) = images.get_mut(&post_processing_material.source_image) {
// TODO: use physical dimensions.
let size = Extent3d{
width: event.width as u32,
height: event.height as u32,
..default()
};
camera_target.texture_descriptor.size = size;
camera_target.resize(camera_target.texture_descriptor.size);
let (
old_main_camera_entity,
old_main_camera,
old_main_camera_velocity,
old_main_camera_transform,
old_main_camera_projection,
) = query_camera.single_mut();
commands.entity(old_main_camera_entity).despawn();
let mut main_camera = Camera2dBundle {
camera_2d: Camera2d {
clear_color: CLEAR_COLOR,
..default()
},
camera: Camera {
priority: old_main_camera.priority - 1,
target: RenderTarget::Image(post_processing_material.source_image.clone()),
..default()
},
..default()
};
let resolution = event.width / event.height;
main_camera.projection.top = 1.0;
main_camera.projection.bottom = -1.0;
main_camera.projection.right = 1.0 * resolution;
main_camera.projection.left = -1.0 * resolution;
main_camera.projection.scaling_mode = ScalingMode::Auto {
min_width: 100.0,
min_height: 100.0,
};
main_camera.projection.scale = old_main_camera_projection.scale;
main_camera.transform = *old_main_camera_transform;
commands
.spawn_bundle(main_camera)
.insert(CameraMain)
.insert(RenderLayers::from_layers(&[0, 1, 2, 3, 4, 5, 6]))
.insert(*old_main_camera_velocity)
.insert(config.movement.clone())
.insert(UiCameraConfig {
show_ui: false,
..default()
});
}
}
}
}
}
Metadata
Metadata
Assignees
Labels
A-RenderingDrawing game state to the screenDrawing game state to the screenC-BugAn unexpected or incorrect behaviorAn unexpected or incorrect behaviorS-Ready-For-ImplementationThis issue is ready for an implementation PR. Go for it!This issue is ready for an implementation PR. Go for it!