use bevy::{ core_pipeline::Skybox, input::mouse::MouseMotion, prelude::*, render::render_resource::{TextureViewDescriptor, TextureViewDimension}, }; fn main() { App::new() .add_plugins(DefaultPlugins) .add_systems(Startup, init) .add_systems(Update, (add_skybox, move_camera)) .run() } fn init(mut commands: Commands) { commands.spawn(Camera3dBundle { camera: Camera { is_active: true, ..default() }, ..default() }); } fn add_skybox( server: Res, query: Query>, mut images: ResMut>, mut commands: Commands, mut handle: Local>>, mut loaded: Local, ) { if !(*loaded) { if let Some(handle) = (*handle).clone() { if let Some(image) = images.get_mut(&handle) { info!("Loaded skybox image"); // NOTE: PNGs do not have any metadata that could indicate they contain a cubemap texture, // so they appear as one texture. The following code reconfigures the texture as necessary. if image.texture_descriptor.array_layer_count() == 1 { image.reinterpret_stacked_2d_as_array( image.texture_descriptor.size.height / image.texture_descriptor.size.width, ); image.texture_view_descriptor = Some(TextureViewDescriptor { dimension: Some(TextureViewDimension::Cube), ..default() }); } query.iter().for_each(|entity| { commands.entity(entity).insert(Skybox(handle.clone())); }); *loaded = true; } } else { *handle = Some(server.load("images/skybox.png")); } } } fn move_camera( mut events: EventReader, mut camera: Query<&mut Transform, With>, ) { events.iter().for_each(|MouseMotion { delta }| { camera.iter_mut().for_each(|mut t| { t.rotate_local_y(-delta.x / 256.0); t.rotate_local_x(-delta.y / 256.0); }) }); }