-
-
Notifications
You must be signed in to change notification settings - Fork 4.3k
Open
Labels
A-AssetsLoad files from disk to use for things like images, models, and soundsLoad files from disk to use for things like images, models, and soundsA-RenderingDrawing game state to the screenDrawing game state to the screenC-BugAn unexpected or incorrect behaviorAn unexpected or incorrect behavior
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<Image>'s get_mut on the handle of that image
What went wrong
The texture stops updating
Minimal code to reproduce
Comment/uncomment lines
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<Assets<Image>>,
camera_query: Query<&Camera, Without<MainCamera>>
) {
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<Time>,
mut camera_query: Query<&mut Transform, (With<Camera>, Without<MainCamera>)>,
) {
let mut camera_transform = camera_query.single_mut();
camera_transform.rotate_around(Vec3::ZERO, Quat::from_axis_angle(Vec3::Y, time.delta_seconds() * 9.))
}
// 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<Assets<Mesh>>,
mut images: ResMut<Assets<Image>>,
mut materials: ResMut<Assets<StandardMaterial>>
) {
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 }
Metadata
Metadata
Assignees
Labels
A-AssetsLoad files from disk to use for things like images, models, and soundsLoad files from disk to use for things like images, models, and soundsA-RenderingDrawing game state to the screenDrawing game state to the screenC-BugAn unexpected or incorrect behaviorAn unexpected or incorrect behavior