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;
|
||||
|
||||
/// 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;
|
||||
|
||||
impl Plugin for BlackHolePlugin {
|
||||
@ -16,7 +21,7 @@ impl Plugin for BlackHolePlugin {
|
||||
.add_systems(Startup, crate::scene::planets::spawn_default_planet)
|
||||
.add_systems(
|
||||
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)
|
||||
// bevy_egui 0.41 requires UI systems to run inside the egui context
|
||||
@ -36,14 +41,34 @@ fn spawn_fullscreen_quad(
|
||||
Err(_) => return,
|
||||
};
|
||||
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((
|
||||
Mesh2d(meshes.add(Rectangle::new(2.0 * aspect, 2.0))),
|
||||
Mesh2d(meshes.add(Rectangle::new(2.0, 2.0))),
|
||||
MeshMaterial2d(materials.add(BlackHoleMaterial::default())),
|
||||
Transform::default(),
|
||||
Transform::default().with_scale(Vec3::new(aspect, 1.0, 1.0)),
|
||||
FullscreenQuad,
|
||||
));
|
||||
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(
|
||||
camera: Res<crate::camera::OrbitCamera>,
|
||||
params: Res<crate::params::BlackHoleParams>,
|
||||
|
||||
@ -35,7 +35,9 @@ pub fn ui_system(
|
||||
});
|
||||
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.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| {
|
||||
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