bevy_symbios_texture
Procedural, tileable texture generation for Bevy.
Generates albedo, normal, and roughness (ORM) maps entirely on the CPU — no asset files required. All surface textures are seamlessly tileable by construction via toroidal 4-D noise mapping. Foliage cards (leaf, twig) produce alpha-masked silhouettes and do not tile.
Bevy compatibility
| bevy_symbios_texture | Bevy |
|---|---|
| 0.2 | 0.18 |
Installation
[]
= "0.2"
Quick start
Synchronous (blocking)
Suitable for startup systems or contexts where a small generation time is acceptable.
use *;
use ;
Asynchronous (non-blocking, recommended)
Offloads pixel math to Bevy's AsyncComputeTaskPool so the main thread is
never stalled.
use *;
use ;
Generators
Surface textures (tileable)
All three tileable generators produce three seamlessly-repeating maps:
| Map | Format | Contents |
|---|---|---|
albedo |
Rgba8UnormSrgb |
Base colour |
normal |
Rgba8Unorm |
Tangent-space normal (R=X, G=Y, B=Z) |
roughness |
Rgba8Unorm |
ORM: R=Occlusion, G=Roughness, B=Metallic |
Upload with [map_to_images] to get repeat-wrapping samplers.
Bark
Domain-warped FBM noise with an anisotropic Worley plate layer for rhytidome furrows, producing fibrous, streaked bark grain.
use BarkConfig;
let config = BarkConfig ;
Rock
Ridged multifractal noise for cracked, faceted stone.
use RockConfig;
let config = RockConfig ;
Ground
Blended dual-scale FBM for organic soil / dirt surfaces.
use GroundConfig;
let config = GroundConfig ;
Foliage cards (alpha-masked)
Foliage generators produce an RGBA8 texture where albedo.alpha encodes the
silhouette (0 = outside, 255 = inside). Upload with [map_to_images_card]
so the sampler does not tile and the alpha channel does not bleed at edges.
Leaf
A discrete leaf silhouette with procedural venation: midrib, secondary veins, a Perlin venule (tertiary vein) network, Worley capillaries, and optional lobed margins.
use LeafConfig;
let config = LeafConfig ;
LeafSampler can also be used directly for per-pixel evaluation without
going through the full generator (e.g., inside a twig compositor):
use ;
let sampler = new;
if let Some = sampler.sample
Twig
A composite foliage card: a tapered, organically curved stem carrying multiple leaf cards. Supports two phyllotaxis modes:
- Monopodial (
sympodial: false) — opposite leaf pairs on a straight axis with a terminal leaf at the apex. - Sympodial (
sympodial: true) — alternate leaves on a zigzag axis, with a terminal leaf at the apex.
use FRAC_PI_2;
use TwigConfig;
use LeafConfig;
let config = TwigConfig ;
Evolutionary parameter search (genetics)
All config types implement symbios_genetics::Genotype, making them
compatible with the evolutionary algorithms in the symbios-genetics crate
(SimpleGA, Nsga2, MapElites).
Each field is independently perturbed during mutation and drawn uniformly from one of two parents during crossover:
use Genotype;
use BarkConfig;
use SeedableRng;
let mut config = default;
let mut rng = seed_from_u64;
config.mutate; // perturb each field with 30 % probability
let parent_b = BarkConfig ;
let child = config.crossover;
The texture_viewer example uses this to mutate any displayed panel when you
click it.
Architecture
TextureGenerator (trait)
│
├── BarkGenerator ─── ToroidalNoise (domain-warped FBM + Worley plates)
├── RockGenerator ─── ToroidalNoise (RidgedMulti)
├── GroundGenerator ─── ToroidalNoise × 2 (dual-scale FBM)
├── LeafGenerator ─── LeafSampler (silhouette + venation)
└── TwigGenerator ─── LeafSampler × N (composite stem + leaves)
│
height_to_normal() → normal map
linear_to_srgb() → albedo encoding
│
TextureMap { albedo, normal, roughness }
│
map_to_images() → GeneratedHandles (repeat sampler)
map_to_images_card() → GeneratedHandles (clamp sampler)
Seamless tiling is provided by [ToroidalNoise], which maps 2-D UV
coordinates onto a 4-D torus so that noise wraps perfectly at every edge:
nx = cos(2π·u) · frequency
ny = sin(2π·u) · frequency
nz = cos(2π·v) · frequency
nw = sin(2π·v) · frequency
Because cos(0) = cos(2π) and sin(0) = sin(2π), u=0 and u=1 always
resolve to the same 4-D point, guaranteeing zero-seam tiling.
Normal maps are derived from the height field via central-difference gradients. For the tileable surface textures (Bark, Rock, Ground) the neighbours wrap toroidally, so the normals are also seamless. For foliage cards (Leaf, Twig) the boundary uses clamp-to-edge so normals do not bleed across the transparent silhouette border.
Colour encoding uses a 4096-entry sRGB lookup table (built once via
OnceLock) to avoid repeated f32::powf calls during rasterisation.
A 256-entry table would be insufficient because the sRGB curve is steep
near zero; 4096 bins keep the maximum quantisation error well below one
count in u8.
Running the viewer example
Displays all five generators (Bark, Rock, Ground, Leaf, Twig) in two rows: albedo maps on top, normal maps below. Left-click any albedo panel to apply a random mutation (rate = 0.3) and regenerate that texture.
License
MIT — see LICENSE.