bevy_tiled_background/
lib.rs

1//! A Bevy plugin for creating tiled, animated UI backgrounds.
2//!
3//! This crate provides a `UiMaterial` implementation that renders a repeating pattern
4//! with support for rotation, staggering, spacing, and scrolling animation.
5//!
6//! # Example
7//!
8//! ```no_run
9//! use bevy::prelude::*;
10//! use bevy_tiled_background::{TiledBackgroundPlugin, TiledBackgroundMaterial};
11//!
12//! fn main() {
13//!     App::new()
14//!         .add_plugins((DefaultPlugins, TiledBackgroundPlugin))
15//!         .add_systems(Startup, setup)
16//!         .run();
17//! }
18//!
19//! fn setup(
20//!     mut commands: Commands,
21//!     asset_server: Res<AssetServer>,
22//!     mut materials: ResMut<Assets<TiledBackgroundMaterial>>,
23//! ) {
24//!     commands.spawn(Camera2d);
25//!
26//!     let material = materials.add(TiledBackgroundMaterial {
27//!         pattern_color: LinearRgba::WHITE,
28//!         scale: 0.5,
29//!         rotation: 35f32.to_radians(),
30//!         stagger: 0.5,
31//!         spacing: 10.0,
32//!         scroll_speed: Vec2::new(20.0, 0.0),
33//!         pattern_texture: asset_server.load("my_pattern.png"),
34//!     });
35//!
36//!     commands.spawn((
37//!         Node {
38//!             width: Val::Percent(100.0),
39//!             height: Val::Percent(100.0),
40//!             ..default()
41//!         },
42//!         MaterialNode(material),
43//!     ));
44//! }
45//! ```
46
47use bevy::{
48    asset::embedded_asset, prelude::*, render::render_resource::AsBindGroup, shader::ShaderRef,
49    ui_render::ui_material::UiMaterial,
50};
51
52/// Plugin that registers the [`TiledBackgroundMaterial`] for use in UI.
53pub struct TiledBackgroundPlugin;
54
55impl Plugin for TiledBackgroundPlugin {
56    fn build(&self, app: &mut App) {
57        embedded_asset!(app, "tiled_background.wgsl");
58
59        app.register_type::<TiledBackgroundMaterial>()
60            .register_asset_reflect::<TiledBackgroundMaterial>()
61            .add_plugins(UiMaterialPlugin::<TiledBackgroundMaterial>::default());
62    }
63}
64
65/// A UI material that renders a tiled, animated pattern.
66#[derive(AsBindGroup, Asset, Debug, Clone, Reflect)]
67pub struct TiledBackgroundMaterial {
68    /// Tint color applied to the pattern. Alpha controls opacity.
69    #[uniform(0)]
70    pub pattern_color: LinearRgba,
71    /// Size multiplier for tiles. `1.0` = native texture size.
72    #[uniform(0)]
73    pub scale: f32,
74    /// Rotation angle in radians.
75    #[uniform(0)]
76    pub rotation: f32,
77    /// Row offset for brick-like patterns. `0.5` = half-tile shift.
78    #[uniform(0)]
79    pub stagger: f32,
80    /// Gap between images in pixels. `0.0` = no gaps.
81    #[uniform(0)]
82    pub spacing: f32,
83    /// Animation speed in pixels per second.
84    #[uniform(0)]
85    pub scroll_speed: Vec2,
86    /// The texture to tile.
87    #[texture(1)]
88    #[sampler(2)]
89    pub pattern_texture: Handle<Image>,
90}
91
92impl Default for TiledBackgroundMaterial {
93    fn default() -> Self {
94        Self {
95            pattern_color: LinearRgba::WHITE,
96            scale: 1.0,
97            rotation: 0.0,
98            stagger: 0.0,
99            spacing: 0.0,
100            scroll_speed: Vec2::ZERO,
101            pattern_texture: Handle::default(),
102        }
103    }
104}
105
106impl UiMaterial for TiledBackgroundMaterial {
107    fn fragment_shader() -> ShaderRef {
108        "embedded://bevy_tiled_background/tiled_background.wgsl".into()
109    }
110}