//! This example illustrates how to create a texture for use with a //! `texture_2d_array` shader uniform variable and then how to sample from //! that texture in the shader by using a `MeshTag` component on the mesh //! entity. use bevy::{ image::{ImageArrayLayout, ImageLoaderSettings}, mesh::MeshTag, prelude::*, reflect::TypePath, render::render_resource::AsBindGroup, shader::ShaderRef, }; /// This example uses a shader source file from the assets subdirectory. const SHADER_ASSET_PATH: &str = "shaders/array_texture.wgsl"; /// Corresponds to the number of layers in the array texture. const TEXTURE_COUNT: u32 = 4; fn main() { App::new() .add_plugins(( DefaultPlugins, MaterialPlugin::::default(), )) .add_systems(Startup, setup) .add_systems(Update, update_mesh_tags) .run(); } fn setup( mut commands: Commands, mut meshes: ResMut>, mut materials: ResMut>, asset_server: Res, ) { // Load the texture. let array_texture = asset_server .load_builder() .with_settings(|settings: &mut ImageLoaderSettings| { settings.array_layout = Some(ImageArrayLayout::RowCount { rows: TEXTURE_COUNT, }); }) .load("textures/array_texture.png"); // light commands.spawn(( DirectionalLight::default(), Transform::from_xyz(3.0, 2.0, 1.0).looking_at(Vec3::ZERO, Vec3::Y), )); // camera commands.spawn(( Camera3d::default(), Transform::from_xyz(5.0, 5.0, 5.0).looking_at(Vec3::new(1.5, 0.0, 0.0), Vec3::Y), )); // Spawn some cubes using the array texture. let mesh_handle = meshes.add(Cuboid::default()); let material_handle = materials.add(ArrayTextureMaterial { array_texture }); for x in -5..=5 { commands.spawn(( Mesh3d(mesh_handle.clone()), MeshMaterial3d(material_handle.clone()), // Pass a different mesh tag to allow selecting different layers of // the array texture in the shader. MeshTag(x as u32 % TEXTURE_COUNT), Transform::from_xyz(x as f32 + 0.5, 0.0, 0.0), )); } } fn update_mesh_tags(time: Res