Skip to content

Commit 7da9d84

Browse files
committed
Example how to repeat texture
1 parent 8067e46 commit 7da9d84

File tree

5 files changed

+120
-0
lines changed

5 files changed

+120
-0
lines changed

Cargo.toml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1148,6 +1148,17 @@ description = "Demonstrates how to process and load custom assets"
11481148
category = "Assets"
11491149
wasm = false
11501150

1151+
[[example]]
1152+
name = "texture_sampler"
1153+
path = "examples/asset/texture_sampler.rs"
1154+
doc-scrape-examples = true
1155+
1156+
[package.metadata.example.texture_sampler]
1157+
name = "Texture sampler configuration"
1158+
description = "How configure image texture to repeat instead of default clamp"
1159+
category = "Assets"
1160+
wasm = true
1161+
11511162
# Async Tasks
11521163
[[example]]
11531164
name = "async_compute"

assets/textures/facade018a.png

46.4 KB
Loading
46.4 KB
Loading

examples/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,7 @@ Example | Description
187187
[Custom Asset](../examples/asset/custom_asset.rs) | Implements a custom asset loader
188188
[Custom Asset IO](../examples/asset/custom_asset_reader.rs) | Implements a custom AssetReader
189189
[Hot Reloading of Assets](../examples/asset/hot_asset_reloading.rs) | Demonstrates automatic reloading of assets when modified on disk
190+
[Texture sampler configuration](../examples/asset/texture_sampler.rs) | How configure image texture to repeat instead of default clamp
190191

191192
## Async Tasks
192193

examples/asset/texture_sampler.rs

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
//! By default Bevy loads images to textures with sampler settings that clamp the image to the edges.
2+
//! This example shows how to change the sampler settings to repeat the image instead.
3+
4+
use bevy::app::App;
5+
use bevy::app::Startup;
6+
use bevy::asset::{AssetServer, Assets};
7+
use bevy::math::Vec3;
8+
use bevy::prelude::DefaultPlugins;
9+
use bevy::prelude::OrthographicProjection;
10+
use bevy::prelude::{Camera2dBundle, ColorMaterial, Commands, Mesh, ResMut, Transform};
11+
use bevy::render::camera::ScalingMode;
12+
use bevy::render::mesh::Indices;
13+
use bevy::render::mesh::PrimitiveTopology;
14+
use bevy::render::texture::{
15+
ImageAddressMode, ImageLoaderSettings, ImageSampler, ImageSamplerDescriptor,
16+
};
17+
use bevy::sprite::MaterialMesh2dBundle;
18+
19+
fn mesh() -> Mesh {
20+
let mut mesh = Mesh::new(PrimitiveTopology::TriangleList);
21+
mesh.insert_attribute(
22+
Mesh::ATTRIBUTE_POSITION,
23+
vec![[0., 0., 0.], [1., 0., 0.], [1., 1., 0.], [0., 1., 0.]],
24+
);
25+
mesh.insert_attribute(
26+
Mesh::ATTRIBUTE_UV_0,
27+
vec![[-1., 2.], [2., 2.], [2., -1.], [-1., -1.]],
28+
);
29+
mesh.set_indices(Some(Indices::U16(vec![0, 1, 2, 2, 3, 0])));
30+
mesh
31+
}
32+
33+
fn setup(
34+
mut commands: Commands,
35+
mut meshes: ResMut<Assets<Mesh>>,
36+
mut materials: ResMut<Assets<ColorMaterial>>,
37+
asset_server: ResMut<AssetServer>,
38+
) {
39+
commands.spawn(Camera2dBundle {
40+
projection: OrthographicProjection {
41+
scaling_mode: ScalingMode::AutoMin {
42+
min_width: 2.,
43+
min_height: 1.,
44+
},
45+
far: 1000.,
46+
near: -1000.,
47+
..OrthographicProjection::default()
48+
},
49+
..Camera2dBundle::default()
50+
});
51+
52+
// Texture from ambientCG.com, licensed under the Creative Commons CC0 1.0 Universal License.
53+
// https://ambientCG.com/a/Facade018A
54+
55+
// By default Bevy loads images to textures with sampler settings that clamp the image to the edges.
56+
let image = asset_server.load("textures/facade018a.png");
57+
58+
// Here we override the sampler settings to repeat the image instead.
59+
let image_repeat = asset_server.load_with_settings(
60+
// We are using another file name, because Bevy ignores different loader settings for the same file.
61+
// This is probably a bug.
62+
"textures/facade018a_copy.png",
63+
|s: &mut ImageLoaderSettings| match &mut s.sampler {
64+
ImageSampler::Default => {
65+
s.sampler = ImageSampler::Descriptor(ImageSamplerDescriptor {
66+
address_mode_u: ImageAddressMode::Repeat,
67+
address_mode_v: ImageAddressMode::Repeat,
68+
..Default::default()
69+
});
70+
}
71+
ImageSampler::Descriptor(sampler) => {
72+
sampler.address_mode_u = ImageAddressMode::Repeat;
73+
sampler.address_mode_v = ImageAddressMode::Repeat;
74+
}
75+
},
76+
);
77+
78+
let mesh = meshes.add(mesh());
79+
80+
commands.spawn(MaterialMesh2dBundle {
81+
mesh: mesh.clone().into(),
82+
material: materials.add(ColorMaterial {
83+
texture: Some(image),
84+
..ColorMaterial::default()
85+
}),
86+
transform: Transform::from_translation(Vec3::new(-0.95, -0.45, 0.))
87+
.with_scale(Vec3::new(0.9, 0.9, 0.9)),
88+
..MaterialMesh2dBundle::default()
89+
});
90+
91+
commands.spawn(MaterialMesh2dBundle {
92+
mesh: mesh.into(),
93+
material: materials.add(ColorMaterial {
94+
texture: Some(image_repeat),
95+
..ColorMaterial::default()
96+
}),
97+
transform: Transform::from_translation(Vec3::new(0.05, -0.45, 0.))
98+
.with_scale(Vec3::new(0.9, 0.9, 0.9)),
99+
..MaterialMesh2dBundle::default()
100+
});
101+
}
102+
103+
fn main() {
104+
App::new()
105+
.add_plugins(DefaultPlugins)
106+
.add_systems(Startup, setup)
107+
.run();
108+
}

0 commit comments

Comments
 (0)