bevyengine / bevyengine/bevy

Assets<Image>'s get_mut prevents the texture of a mesh using the Image as a texture to be updated

Open
#8,767 3 comments 0 reactions 0 assignees View on GitHub
A-Assets A-Rendering C-Bug
Dominant language
Rust
Stars
48.2k
Forks
4.8k
Avg merge
3d 22h
Merged PRs (30d)
161

Description

## Bevy version

v0.10.1

## What you did

Render a camera to an image, use that image as a texture of a mesh, use `Assets`'s `get_mut` on the handle of that image

## What went wrong

The texture stops updating

## Minimal code to reproduce

Comment/uncomment lines

```rust
use bevy::{
prelude::*,
render::{
render_resource::*,
camera::RenderTarget
},
};

#[derive(Component)]
struct MainCamera; // Camera that is used to render to the window, not the image

fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_startup_system(setup)
.add_system(rotate_other_camera)
// comment and uncomment this line
//.add_system(get_mut_image)
.run();
}

fn get_mut_image (
mut images: ResMut>,
camera_query: Query<&Camera, Without>
) {
let camera = camera_query.single();
if let RenderTarget::Image(handle) = camera.target.clone() {
images.get_mut(&handle.clone()); // This line is the culprit, you can uncomment it too
}
}

// Turn the texture rendering camera to make the texture update
fn rotate_other_camera(
time: Res

// This is adapted from the Bevy example to render to a texture: https://github.com/bevyengine/bevy/blob/latest/examples/3d/render_to_texture.rs
fn setup(
mut commands: Commands,
mut meshes: ResMut>,
mut images: ResMut>,
mut materials: ResMut>
) {
commands.insert_resource(AmbientLight {
color: Color::WHITE,
brightness: 0.3,
});

// Main camera (displayed in window)
commands.spawn((
Camera3dBundle {
transform: Transform::from_xyz(0.0, 0., 20.0).looking_at(Vec3::ZERO, Vec3::Y),
..default()
},
MainCamera
));

// Second camera (renders to an image, gets rotated, and the image doesn't update if get_mut_image)
let size = Extent3d {width: 450, height: 450, ..default()};
let mut camera_image = Image {
texture_descriptor: TextureDescriptor {
label: None,
size,
dimension: TextureDimension::D2,
format: TextureFormat::Bgra8UnormSrgb,
mip_level_count: 1,
sample_count: 1,
usage: TextureUsages::TEXTURE_BINDING
| TextureUsages::COPY_DST
| TextureUsages::RENDER_ATTACHMENT,
view_formats: &[],
},
..default()
};
camera_image.resize(size);
let camera_image = images.add(camera_image);

commands.spawn(
Camera3dBundle {
camera: Camera {
order: -1,
target: RenderTarget::Image(camera_image),
..default()
},
transform: Transform::from_xyz(0., 0., 10.),
..default()
}
);

// Object the image is rendered to
let material_handle = materials.add(StandardMaterial {
base_color_texture: Some(camera_image.clone()),
reflectance: 0.02,
unlit: false,
..default()
});
commands.spawn((
PbrBundle {
mesh: meshes.add(Mesh::from(shape::Cube::new(5.))),
material: material_handle,
transform: Transform::from_xyz(0., 6., 0.),
..default()
},
));

// Normal object to have something to look at
let sphere_mesh = meshes.add(Mesh::from(shape::Cube::new(5.)));
let debug_material = materials.add(StandardMaterial {
base_color_texture: Some(images.add(uv_debug_texture())),
..default()
});
commands.spawn(PbrBundle {
mesh: sphere_mesh,
material: debug_material,
..default()
});
}

// This is taken from the 3d_shapes example: https://bevyengine.org/examples/3d/3d-shapes/
pub fn uv_debug_texture() -> Image {
const TEXTURE_SIZE: usize = 8;

let mut palette: [u8; 32] = [
255, 102, 159, 255, 255, 159, 102, 255, 236, 255, 102, 255, 121, 255, 102, 255, 102, 255,
198, 255, 102, 198, 255, 255, 121, 102, 255, 255, 236, 102, 255, 255,
];

let mut texture_data = [0; TEXTURE_SIZE * TEXTURE_SIZE * 4];
for y in 0..TEXTURE_SIZE {
let offset = TEXTURE_SIZE * y * 4;
texture_data[offset..(offset + TEXTURE_SIZE * 4)].copy_from_slice(&palette);
palette.rotate_right(4);
}

Image::new_fill(
Extent3d {
width: TEXTURE_SIZE as u32,
height: TEXTURE_SIZE as u32,
depth_or_array_layers: 1,
},
TextureDimension::D2,
&texture_data,
TextureFormat::Rgba8UnormSrgb,
)
}
```

## Additional information

Discord threads (potentially) related:
- https://discord.com/channels/691052431525675048/1115608944266719322
- https://discord.com/channels/691052431525675048/1115635786751164561
- https://discord.com/channels/691052431525675048/1019697973933899910/threads/1093930187802017953
- https://discord.com/channels/691052431525675048/691052431974465548/1115594632122863687

## Potential relevant system information

- Rust version:
- Operating System: Linux Mint MATE 1.26, x11
- `AdapterInfo { name: "Intel(R) Xe Graphics (TGL GT2)", vendor: 32902, device: 39497, device_type: IntegratedGpu, driver: "Intel open-source Mesa driver", driver_info: "Mesa 22.2.5", backend: Vulkan }`

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.