Skip to content

Regression: rendered texture not updating after change to Image #17350

Open
@bas-ie

Description

Bevy version

0.15.1

What you did

Minimal repro
use bevy::{
    asset::RenderAssetUsages,
    color::palettes::css,
    prelude::*,
    render::render_resource::{Extent3d, TextureDimension, TextureFormat},
};

fn main() {
    App::new()
        .add_plugins(DefaultPlugins)
        .add_systems(Startup, init)
        .add_systems(FixedUpdate, draw)
        .run();
}

fn init(
    mut commands: Commands,
    mut images: ResMut<Assets<Image>>,
    mut materials: ResMut<Assets<ColorMaterial>>,
    mut meshes: ResMut<Assets<Mesh>>,
) {
    let image = Image::new_fill(
        Extent3d {
            width: 256,
            height: 256,
            depth_or_array_layers: 1,
        },
        TextureDimension::D2,
        &(css::REBECCA_PURPLE.to_u8_array()),
        TextureFormat::Rgba8UnormSrgb,
        RenderAssetUsages::MAIN_WORLD | RenderAssetUsages::RENDER_WORLD,
    );
    let image_handle = images.add(image);
    let mesh = meshes.add(Rectangle::new(256., 256.));
    let material = materials.add(image_handle);

    commands.spawn((Camera2d, Mesh2d(mesh), MeshMaterial2d(material)));
}

fn draw(
    mut images: ResMut<Assets<Image>>,
    material: Single<&MeshMaterial2d<ColorMaterial>>,
    mut materials: ResMut<Assets<ColorMaterial>>,
) {
    let Some(m) = materials.get(*material) else {
        return;
    };

    let Some(texture) = &m.texture else {
        return;
    };

    let Some(img) = images.get_mut(texture) else {
        return;
    };

    for x in 0..50 {
        for y in 0..50 {
            let _ = img.set_color_at(x, y, Color::WHITE);
        }
    }
    // This call is required to update render.
    materials.get_mut(*material);
}

Create an Image. Add it to a MeshMaterial2d, and render the material using a Mesh2d. In the FixedUpdate schedule, modify the Image asset.

What went wrong

The changes will not be rendered unless a call is made to materials.get_mut(&handle) after the changes have been made.

Additional information

It appears this may have been "re-broken" for quite awhile after being fixed in 107dd73. It's also possible that this is "working as intended" in the retained rendering world we live in, but I'm not flash enough to understand all the possible implications!

For some reason this behaviour is not evident in Update, only FixedUpdate. I have no idea why! I can also make it manifest in Update if I wait on mouse input e.g. by "drawing" on the image using the cursor, which smacks of a timing issue but no clue what.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Labels

    A-RenderingDrawing game state to the screenC-BugAn unexpected or incorrect behaviorP-RegressionFunctionality that used to work but no longer does. Add a test for this!S-Needs-InvestigationThis issue requires detective work to figure out what's going wrong

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions