Skip to content

Conversation

@tychedelia
Copy link
Member

For Processing, we sometimes want to accumulate multiple render updates in the intermediate view texture prior to calling present. Right now, any time the render graph runs it will try to unconditionally present, regardless of whether any work has actually been written to the output target causing unnecessary churn and wasting battery. This is particularly problematic for us as we have a requirement that only a single camera can be active at a time, so to render 3 cameras we need to run app update 3 times at least.

NB: previous comments regarding ViewTarget may be misleading. You don't have to drop views when re-creating the swapchain, just the existing texture as far as I can tell.

To test:

//! A simple 3D scene with light shining over a cube sitting on a plane.

use bevy::camera::CameraOutputMode;
use bevy::prelude::*;

fn main() {
    App::new()
        .add_plugins(DefaultPlugins)
        .add_systems(Startup, setup)
        .add_systems(Update, update)
        .run();
}

/// set up a simple 3D scene
fn setup(
    mut commands: Commands,
    mut meshes: ResMut<Assets<Mesh>>,
    mut materials: ResMut<Assets<StandardMaterial>>,
) {
    // circular base
    commands.spawn((
        Mesh3d(meshes.add(Circle::new(4.0))),
        MeshMaterial3d(materials.add(Color::WHITE)),
        Transform::from_rotation(Quat::from_rotation_x(-std::f32::consts::FRAC_PI_2)),
    ));
    // cube
    commands.spawn((
        Mesh3d(meshes.add(Cuboid::new(1.0, 1.0, 1.0))),
        MeshMaterial3d(materials.add(Color::srgb_u8(124, 144, 255))),
        Transform::from_xyz(0.0, 0.5, 0.0),
    ));
    // light
    commands.spawn((
        PointLight {
            shadows_enabled: true,
            ..default()
        },
        Transform::from_xyz(4.0, 8.0, 4.0),
    ));
    // camera
    commands.spawn((
        Camera3d::default(),
        Transform::from_xyz(-2.5, 4.5, 9.0).looking_at(Vec3::ZERO, Vec3::Y),
    ));
}

fn update(buttons: Res<ButtonInput<KeyCode>>, mut cameras: Query<&mut Camera>) {
    if buttons.just_pressed(KeyCode::Space) {
        for mut camera in &mut cameras {
            match camera.output_mode {
                CameraOutputMode::Write { .. } => {
                    camera.output_mode = CameraOutputMode::Skip;
                }
                CameraOutputMode::Skip => {
                    camera.output_mode = CameraOutputMode::default();
                }
            }
        }
    }
}

@tychedelia tychedelia added this to the 0.18 milestone Nov 17, 2025
@tychedelia tychedelia added C-Feature A new feature, making something new possible A-Rendering Drawing game state to the screen S-Needs-Review Needs reviewer attention (from anyone!) to move forward labels Nov 17, 2025
@alice-i-cecile alice-i-cecile added S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it and removed S-Needs-Review Needs reviewer attention (from anyone!) to move forward labels Nov 17, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-Rendering Drawing game state to the screen C-Feature A new feature, making something new possible S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

4 participants