//! Load a cubemap texture onto a cube like a skybox and cycle through different compressed texture formats use std::f32::consts::PI; use bevy::{ asset::LoadState, input::mouse::MouseMotion, pbr::{MaterialPipeline, MaterialPipelineKey}, prelude::*, reflect::TypeUuid, render::{ mesh::MeshVertexBufferLayout, render_asset::RenderAssets, render_resource::{ AsBindGroup, AsBindGroupError, BindGroupDescriptor, BindGroupEntry, BindGroupLayout, BindGroupLayoutDescriptor, BindGroupLayoutEntry, BindingResource, BindingType, OwnedBindingResource, PreparedBindGroup, RenderPipelineDescriptor, SamplerBindingType, ShaderRef, ShaderStages, SpecializedMeshPipelineError, TextureSampleType, TextureViewDescriptor, TextureViewDimension, }, renderer::RenderDevice, texture::{CompressedImageFormats, FallbackImage}, }, }; const CUBEMAPS: &[(&str, CompressedImageFormats)] = &[ ( "textures/Ryfjallet_cubemap.png", CompressedImageFormats::NONE, ), ( "textures/Ryfjallet_cubemap_astc4x4.ktx2", CompressedImageFormats::ASTC_LDR, ), ( "textures/Ryfjallet_cubemap_bc7.ktx2", CompressedImageFormats::BC, ), ( "textures/Ryfjallet_cubemap_etc2.ktx2", CompressedImageFormats::ETC2, ), ]; fn main() { App::new() .add_plugins(DefaultPlugins) .add_plugin(MaterialPlugin::::default()) .add_startup_system(setup) .add_system(cycle_cubemap_asset) .add_system(asset_loaded.after(cycle_cubemap_asset)) .add_system(camera_controller) .add_system(animate_light_direction) .run(); } #[derive(Resource)] struct Cubemap { is_loaded: bool, index: usize, image_handle: Handle, } fn setup(mut commands: Commands, asset_server: Res) { // directional 'sun' light commands.spawn(DirectionalLightBundle { directional_light: DirectionalLight { illuminance: 32000.0, ..default() }, transform: Transform::from_xyz(0.0, 2.0, 0.0) .with_rotation(Quat::from_rotation_x(-PI / 4.)), ..default() }); let skybox_handle = asset_server.load(CUBEMAPS[0].0); // camera commands.spawn(( Camera3dBundle { transform: Transform::from_xyz(0.0, 0.0, 8.0).looking_at(Vec3::ZERO, Vec3::Y), ..default() }, CameraController::default(), )); // ambient light // NOTE: The ambient light is used to scale how bright the environment map is so with a bright // environment map, use an appropriate colour and brightness to match commands.insert_resource(AmbientLight { color: Color::rgb_u8(210, 220, 240), brightness: 1.0, }); commands.insert_resource(Cubemap { is_loaded: false, index: 0, image_handle: skybox_handle, }); } const CUBEMAP_SWAP_DELAY: f32 = 3.0; fn cycle_cubemap_asset( time: Res