1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
//! `bevy_symbios_texture` — procedural texture generation for Bevy.
//!
//! # Generators
//!
//! **Tileable surface textures** (bark, rock, ground, brick, plank, concrete,
//! metal, shingle, pavers, stucco, ashlar, cobblestone, thatch, marble,
//! corrugated, asphalt, wainscoting, encaustic, fabric, sand, snow, ice,
//! lava): wrap seamlessly via toroidal 4-D noise mapping. Upload with
//! [`map_to_images`] to get repeat-wrapping samplers. `lava` additionally
//! produces an emissive (glow) map.
//!
//! **Alpha-masked cards** (leaf, twig, window, stained_glass, iron_grille,
//! chain_link, log_end): produce silhouettes with per-pixel alpha that must
//! not tile. Upload with [`map_to_images_card`] to get clamp-to-edge
//! samplers.
//!
//! **Sprite atlases** (soft_disc, spark, snowflake, puff, ring, petal,
//! shard, leaf_sprite, flame, flower): alpha-silhouette cards aimed at
//! particle billboards. Each can bake a `variant_rows × variant_cols`
//! atlas where every cell renders a per-cell-seeded variant of the same
//! config — one bake gives a particle system per-particle shape variety via
//! random atlas frames. Shared conventions live in [`sprite`]; upload with
//! [`map_to_images_card`].
//!
//! # Architecture
//! Every generator implements [`TextureGenerator`], which produces a
//! [`TextureMap`] (raw pixel buffers for albedo, normal, roughness/ORM).
//!
//! Seamless tiling for surface textures is guaranteed by the [`ToroidalNoise`]
//! wrapper, which maps 2-D UV coordinates to a 4-D torus so noise wraps at
//! every edge with no seam.
//!
//! Both upload functions generate a full mipmap chain with type-correct
//! averaging: sRGB-linear averaging for albedo, renormalized averaging for
//! normal maps, and direct linear averaging for ORM maps.
//!
//! # Plugin & async generation
//! [`SymbiosTexturePlugin`] registers the polling systems and applies an
//! [`AsyncTextureConfig`] to a private rayon thread pool dedicated to
//! texture generation. Spawn [`async_gen::PendingTexture`] components to
//! offload work; the result lands on the entity as
//! [`async_gen::TextureReady`].
//!
//! # Procedural materials
//! [`build_procedural_material_async`] is a one-shot helper that returns a
//! `Handle<StandardMaterial>` immediately and patches the generated textures
//! in once the background task completes. Pair with an optional
//! [`TextureCache`] resource to avoid regenerating identical configs.
//!
//! # Animated parameters
//! [`AnimatedProceduralMaterial`] drives time-varying texture parameters by
//! re-evaluating a closure each frame, regenerating only when the
//! fingerprint of the resulting [`TextureConfig`] changes (with a
//! configurable wall-clock cooldown).
//!
//! # Genetics
//! All config types implement `symbios_genetics::Genotype` (see [`genetics`]),
//! making them compatible with evolutionary search algorithms such as
//! `SimpleGA`, `Nsga2`, and `MapElites` from the `symbios-genetics` crate.
//!
//! [`TextureCache`]: cache::TextureCache
//! [`TextureConfig`]: material::TextureConfig
pub
pub
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ToroidalNoise;
pub use ;
pub use ;
pub use ;
use *;
/// Bevy plugin — registers the async-generation polling system and applies
/// the [`AsyncTextureConfig`] to the private texture-generation thread pool.
///
/// Construct via [`Default`] for the standard [`DEFAULT_POOL_THREADS`] cap,
/// or set [`SymbiosTexturePlugin::config`] explicitly for custom pool sizing:
///
/// ```rust,ignore
/// app.add_plugins(SymbiosTexturePlugin {
/// config: AsyncTextureConfig { pool_threads: 0 }, // auto = cores / 2
/// });
/// ```
///
/// The pool configuration is applied at plugin-build time and frozen on the
/// first generation request — re-adding the plugin with a different config
/// after a task has been dispatched has no effect.