array_texture/
array_texture.rs1use bevy::{
7 image::{ImageArrayLayout, ImageLoaderSettings},
8 mesh::MeshTag,
9 prelude::*,
10 reflect::TypePath,
11 render::render_resource::AsBindGroup,
12 shader::ShaderRef,
13};
14
15const SHADER_ASSET_PATH: &str = "shaders/array_texture.wgsl";
17
18const TEXTURE_COUNT: u32 = 4;
20
21fn main() {
22 App::new()
23 .add_plugins((
24 DefaultPlugins,
25 MaterialPlugin::<ArrayTextureMaterial>::default(),
26 ))
27 .add_systems(Startup, setup)
28 .add_systems(Update, update_mesh_tags)
29 .run();
30}
31
32fn setup(
33 mut commands: Commands,
34 mut meshes: ResMut<Assets<Mesh>>,
35 mut materials: ResMut<Assets<ArrayTextureMaterial>>,
36 asset_server: Res<AssetServer>,
37) {
38 let array_texture = asset_server
40 .load_builder()
41 .with_settings(|settings: &mut ImageLoaderSettings| {
42 settings.array_layout = Some(ImageArrayLayout::RowCount {
43 rows: TEXTURE_COUNT,
44 });
45 })
46 .load("textures/array_texture.png");
47
48 commands.spawn((
50 DirectionalLight::default(),
51 Transform::from_xyz(3.0, 2.0, 1.0).looking_at(Vec3::ZERO, Vec3::Y),
52 ));
53
54 commands.spawn((
56 Camera3d::default(),
57 Transform::from_xyz(5.0, 5.0, 5.0).looking_at(Vec3::new(1.5, 0.0, 0.0), Vec3::Y),
58 ));
59
60 let mesh_handle = meshes.add(Cuboid::default());
62 let material_handle = materials.add(ArrayTextureMaterial { array_texture });
63 for x in -5..=5 {
64 commands.spawn((
65 Mesh3d(mesh_handle.clone()),
66 MeshMaterial3d(material_handle.clone()),
67 MeshTag(x as u32 % TEXTURE_COUNT),
70 Transform::from_xyz(x as f32 + 0.5, 0.0, 0.0),
71 ));
72 }
73}
74
75fn update_mesh_tags(time: Res<Time>, mut query: Query<&mut MeshTag>, mut timer: Local<Timer>) {
76 if timer.duration().is_zero() {
78 *timer = Timer::from_seconds(1.5, TimerMode::Repeating);
79 }
80
81 timer.tick(time.delta());
82 if timer.just_finished() {
83 for mut tag in query.iter_mut() {
84 tag.0 = (tag.0 + 1) % TEXTURE_COUNT;
87 }
88 }
89}
90
91#[derive(Asset, TypePath, AsBindGroup, Debug, Clone)]
92struct ArrayTextureMaterial {
93 #[texture(0, dimension = "2d_array")]
94 #[sampler(1)]
95 array_texture: Handle<Image>,
96}
97
98impl Material for ArrayTextureMaterial {
99 fn fragment_shader() -> ShaderRef {
100 SHADER_ASSET_PATH.into()
101 }
102}