//! Shows how to render UI to a texture. Useful for displaying UI in 3D space. use std::f32::consts::PI; use bevy::{ color::palettes::css::GOLD, prelude::*, render::{ camera::RenderTarget, render_asset::RenderAssetUsages, render_resource::{Extent3d, TextureDimension, TextureFormat, TextureUsages}, }, }; fn main() { App::new() .add_plugins(DefaultPlugins) .add_systems(Startup, setup) .add_systems(Update, rotator_system) .run(); } // Marks the cube, to which the UI texture is applied. #[derive(Component)] struct Cube; fn setup( mut commands: Commands, mut meshes: ResMut>, mut materials: ResMut>, mut images: ResMut>, ) { let size = Extent3d { width: 512, height: 512, ..default() }; // This is the texture that will be rendered to. let mut image = Image::new_fill( size, TextureDimension::D2, &[0, 0, 0, 0], TextureFormat::Bgra8UnormSrgb, RenderAssetUsages::default(), ); // You need to set these texture usage flags in order to use the image as a render target image.texture_descriptor.usage = TextureUsages::TEXTURE_BINDING | TextureUsages::COPY_DST | TextureUsages::RENDER_ATTACHMENT; let image_handle = images.add(image); // Light commands.spawn(DirectionalLight::default()); let texture_camera = commands .spawn(( Camera2d, Camera { target: RenderTarget::Image(image_handle.clone()), ..default() }, )) .id(); commands .spawn(( NodeBundle { style: Style { // Cover the whole image width: Val::Percent(100.), height: Val::Percent(100.), flex_direction: FlexDirection::Column, justify_content: JustifyContent::Center, align_items: AlignItems::Center, ..default() }, background_color: GOLD.into(), ..default() }, TargetCamera(texture_camera), )) .with_children(|parent| { parent.spawn(TextBundle::from_section( "This is a cube", TextStyle { font_size: 40.0, color: Color::BLACK, ..default() }, )); }); let cube_size = 4.0; let cube_handle = meshes.add(Cuboid::new(cube_size, cube_size, cube_size)); // This material has the texture that has been rendered. let material_handle = materials.add(StandardMaterial { base_color_texture: Some(image_handle), reflectance: 0.02, unlit: false, ..default() }); // Cube with material containing the rendered UI texture. commands.spawn(( Mesh3d(cube_handle), MeshMaterial3d(material_handle), Transform::from_xyz(0.0, 0.0, 1.5).with_rotation(Quat::from_rotation_x(-PI / 5.0)), Cube, )); // The main pass camera. commands.spawn(( Camera3d::default(), Transform::from_xyz(0.0, 0.0, 15.0).looking_at(Vec3::ZERO, Vec3::Y), )); } const ROTATION_SPEED: f32 = 0.5; fn rotator_system(time: Res