fix: keep full-screen quad filled on window resize
The quad mesh was built once at startup with the initial aspect ratio, so widening the window afterward left empty edges. Add a FullscreenQuad marker component and a fit_quad_to_window system that rescales the quad's Transform to the live aspect each frame (only mutating on change). Also remove the misleading 'Render scale' slider — it isn't wired to a real sub-resolution render target in Phase 1 (the full-screen quad always renders at window resolution). Lowering Steps is the real perf lever. Documented in a code comment for future work.
This commit is contained in:
parent
7e0ac65d55
commit
1e8cd93bc3
@ -3,6 +3,11 @@ use bevy::sprite_render::Material2dPlugin;
|
|||||||
|
|
||||||
use super::material::BlackHoleMaterial;
|
use super::material::BlackHoleMaterial;
|
||||||
|
|
||||||
|
/// Marks the full-screen quad so the resize system can find and rescale it
|
||||||
|
/// when the window's aspect ratio changes (the mesh is built once at startup).
|
||||||
|
#[derive(Component)]
|
||||||
|
struct FullscreenQuad;
|
||||||
|
|
||||||
pub struct BlackHolePlugin;
|
pub struct BlackHolePlugin;
|
||||||
|
|
||||||
impl Plugin for BlackHolePlugin {
|
impl Plugin for BlackHolePlugin {
|
||||||
@ -16,7 +21,7 @@ impl Plugin for BlackHolePlugin {
|
|||||||
.add_systems(Startup, crate::scene::planets::spawn_default_planet)
|
.add_systems(Startup, crate::scene::planets::spawn_default_planet)
|
||||||
.add_systems(
|
.add_systems(
|
||||||
Update,
|
Update,
|
||||||
(crate::camera::orbit_controller, mirror_params),
|
(crate::camera::orbit_controller, mirror_params, fit_quad_to_window),
|
||||||
)
|
)
|
||||||
.add_systems(Update, crate::scene::planets::upload_planets)
|
.add_systems(Update, crate::scene::planets::upload_planets)
|
||||||
// bevy_egui 0.41 requires UI systems to run inside the egui context
|
// bevy_egui 0.41 requires UI systems to run inside the egui context
|
||||||
@ -36,14 +41,34 @@ fn spawn_fullscreen_quad(
|
|||||||
Err(_) => return,
|
Err(_) => return,
|
||||||
};
|
};
|
||||||
let aspect = win.width() / win.height();
|
let aspect = win.width() / win.height();
|
||||||
|
// The mesh is a unit square (2x2 covers [-1,1]); we rescale via Transform
|
||||||
|
// in fit_quad_to_window whenever the aspect changes.
|
||||||
commands.spawn((
|
commands.spawn((
|
||||||
Mesh2d(meshes.add(Rectangle::new(2.0 * aspect, 2.0))),
|
Mesh2d(meshes.add(Rectangle::new(2.0, 2.0))),
|
||||||
MeshMaterial2d(materials.add(BlackHoleMaterial::default())),
|
MeshMaterial2d(materials.add(BlackHoleMaterial::default())),
|
||||||
Transform::default(),
|
Transform::default().with_scale(Vec3::new(aspect, 1.0, 1.0)),
|
||||||
|
FullscreenQuad,
|
||||||
));
|
));
|
||||||
commands.spawn(Camera2d);
|
commands.spawn(Camera2d);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Rescale the full-screen quad so it always covers the camera's view, even
|
||||||
|
/// after the window is resized. Camera2d's default projection spans y∈[-1,1]
|
||||||
|
/// and x∈[-aspect, aspect]; scaling the unit quad by (aspect, 1, 1) fills it.
|
||||||
|
fn fit_quad_to_window(window: Query<&Window>, mut quad: Query<&mut Transform, With<FullscreenQuad>>) {
|
||||||
|
let win = match window.single() {
|
||||||
|
Ok(w) => w,
|
||||||
|
Err(_) => return,
|
||||||
|
};
|
||||||
|
let aspect = win.width() / win.height();
|
||||||
|
for mut transform in &mut quad {
|
||||||
|
// Only mutate on change to avoid spamming change detection.
|
||||||
|
if transform.scale.x != aspect {
|
||||||
|
transform.scale.x = aspect;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn mirror_params(
|
fn mirror_params(
|
||||||
camera: Res<crate::camera::OrbitCamera>,
|
camera: Res<crate::camera::OrbitCamera>,
|
||||||
params: Res<crate::params::BlackHoleParams>,
|
params: Res<crate::params::BlackHoleParams>,
|
||||||
|
|||||||
@ -35,7 +35,9 @@ pub fn ui_system(
|
|||||||
});
|
});
|
||||||
egui::CollapsingHeader::new("Renderer").show(ui, |ui| {
|
egui::CollapsingHeader::new("Renderer").show(ui, |ui| {
|
||||||
ui.add(egui::Slider::new(&mut params.steps, 50..=600).text("Steps"));
|
ui.add(egui::Slider::new(&mut params.steps, 50..=600).text("Steps"));
|
||||||
ui.add(egui::Slider::new(&mut params.render_scale, 0.5..=1.0).text("Render scale"));
|
// NOTE: render_scale is intentionally not exposed — it isn't wired
|
||||||
|
// to a real sub-resolution render target in Phase 1 (the full-screen
|
||||||
|
// quad always renders at window resolution). Lower `Steps` to gain FPS.
|
||||||
});
|
});
|
||||||
egui::CollapsingHeader::new("Background").show(ui, |ui| {
|
egui::CollapsingHeader::new("Background").show(ui, |ui| {
|
||||||
ui.add(egui::Slider::new(&mut params.star_intensity, 0.0..=3.0).text("Star intensity"));
|
ui.add(egui::Slider::new(&mut params.star_intensity, 0.0..=3.0).text("Star intensity"));
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user