Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bevyengine
GitHub Repository: bevyengine/bevy
Path: blob/main/examples/shader/array_texture.rs
9304 views
1
//! This example illustrates how to create a texture for use with a
2
//! `texture_2d_array<f32>` shader uniform variable and then how to sample from
3
//! that texture in the shader by using a `MeshTag` component on the mesh
4
//! entity.
5
6
use bevy::{
7
image::{ImageArrayLayout, ImageLoaderSettings},
8
mesh::MeshTag,
9
prelude::*,
10
reflect::TypePath,
11
render::render_resource::AsBindGroup,
12
shader::ShaderRef,
13
};
14
15
/// This example uses a shader source file from the assets subdirectory.
16
const SHADER_ASSET_PATH: &str = "shaders/array_texture.wgsl";
17
18
/// Corresponds to the number of layers in the array texture.
19
const TEXTURE_COUNT: u32 = 4;
20
21
fn 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
32
fn setup(
33
mut commands: Commands,
34
mut meshes: ResMut<Assets<Mesh>>,
35
mut materials: ResMut<Assets<ArrayTextureMaterial>>,
36
asset_server: Res<AssetServer>,
37
) {
38
// Load the texture.
39
let array_texture = asset_server.load_with_settings(
40
"textures/array_texture.png",
41
|settings: &mut ImageLoaderSettings| {
42
settings.array_layout = Some(ImageArrayLayout::RowCount {
43
rows: TEXTURE_COUNT,
44
});
45
},
46
);
47
48
// light
49
commands.spawn((
50
DirectionalLight::default(),
51
Transform::from_xyz(3.0, 2.0, 1.0).looking_at(Vec3::ZERO, Vec3::Y),
52
));
53
54
// camera
55
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
// Spawn some cubes using the array texture.
61
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
// Pass a different mesh tag to allow selecting different layers of
68
// the array texture in the shader.
69
MeshTag(x as u32 % TEXTURE_COUNT),
70
Transform::from_xyz(x as f32 + 0.5, 0.0, 0.0),
71
));
72
}
73
}
74
75
fn update_mesh_tags(time: Res<Time>, mut query: Query<&mut MeshTag>, mut timer: Local<Timer>) {
76
// Initialize the timer on the first run.
77
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
// Cycle through the texture layers to demonstrate that we can
85
// select different layers of the array texture at runtime.
86
tag.0 = (tag.0 + 1) % TEXTURE_COUNT;
87
}
88
}
89
}
90
91
#[derive(Asset, TypePath, AsBindGroup, Debug, Clone)]
92
struct ArrayTextureMaterial {
93
#[texture(0, dimension = "2d_array")]
94
#[sampler(1)]
95
array_texture: Handle<Image>,
96
}
97
98
impl Material for ArrayTextureMaterial {
99
fn fragment_shader() -> ShaderRef {
100
SHADER_ASSET_PATH.into()
101
}
102
}
103
104