CPU drawing into 2D texture is not updated to the GPU when using any 2D materials
- Dominant language
- Rust
- Stars
- 48.2k
- Forks
- 4.8k
- Avg merge
- 3d 22h
- Merged PRs (30d)
- 161
Description
## Bevy version
The release number or commit hash of the version you're using.
bevy = "0.16.1"
## \[Optional\] Relevant system information
```
AdapterInfo { name: "Apple M3", vendor: 0, device: 0, device_type: IntegratedGpu, driver: "", driver_info: "", backend: Metal }
```
It should reproduce on any other GPU
## What you did
### Create a sprite using any 2D material with custom texture, like ColorMaterial or something custom
```rust
let image = Image::new_fill(
// 2D image of size
Extent3d {
width: s as u32,
height: s as u32,
depth_or_array_layers: 1,
},
TextureDimension::D2,
// Initialize it with a beige color
&(color),
// Use the same encoding as the color we set
TextureFormat::Rgba8UnormSrgb,
RenderAssetUsages::RENDER_WORLD | RenderAssetUsages::MAIN_WORLD,
);
let handle = images.add(image);
let mat = ColorMaterial {
texture: handle.clone(),
};
let material_handle = materials.add(mat);
let mesh = meshes.add(Rectangle::new(
s as f32,
s as f32,
));
commands.spawn((
MeshMaterial2d(material_handle.clone()),
Mesh2d(mesh),
Transform::from_xyz(0.0, 0.0, 100000.0),
));
commands.insert_resource(LightOverlayTextureHandle(handle)); // my custom handle res
commands.insert_resource(LightOverlayMaterialHandle(material_handle));
```
### Draw to that texture in a system
```rust
pub fn draw_random_color_pixel(
light_texture_handle: Res,
light_material_handle: Res,
mut images: ResMut>,
mut materials: ResMut>,
) {
// Get mutable reference to the image
if let Some(image) = images.get_mut(&light_texture_handle.0) {
let width = image.size().x;
let height = image.size().y;
// Generate random coordinates and color
let mut rng = rand::rng();
let x = rng.gen_range(0..width);
let y = rng.gen_range(0..height);
let color = Color::srgb(
rng.gen_range(0.0..=1.0),
rng.gen_range(0.0..=1.0),
rng.gen_range(0.0..=1.0),
);
// Set the pixel
image.set_color_at(x, y, color).unwrap();
}
// placeholder for a hotfix
}
```
## What went wrong
If using FixedUpdate sheduler - no draws happen on the screen, texture is not updated
If using Update scheduler - only first update is visible on the screen, then texture is not updated
### Hot fix:
Add `materials.get_mut(&light_material_handle.0)` to the end of your system, that does literally nothing and does not actually mutate material, but it assumes that material has changed and updates the texture, this way it works perfectly.
I believe this is not how it is supposed to work.
## Additional information
When using example with sprite::from_image(), then it tracks texture changes correctly. It should work the same when Material2D is used.
Contributor guide
Assessment
This issue has not been assessed yet.