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
//! Growing trees in the vertex shader.
//!
//! A tree with [`GpuGrowth`] is built once, at maturity, and uploaded once.
//! Every vertex carries which node it belongs to and where it sits relative to
//! that node's axis; each frame the CPU ages the skeleton ([`Skeleton::aged`])
//! and writes one small record per node into a storage buffer, and the vertex
//! shader (`growth.wesl`) moves every vertex to where the CPU path would have
//! put it. Nothing else is uploaded.
//!
//! [`Skeleton::aged`]: crate::Skeleton::aged
use App;
use ;
use *;
use ;
use MaterialPlugin;
use Reflect;
use RenderApp;
use ShaderBuffer;
pub
pub use ;
/// Per-vertex: the node (`Node::id`) in the low word, the placement class
/// (low 8 bits) and a leaf's ordinal (the rest) in the high word.
pub const ATTRIBUTE_GROWTH_ID: MeshVertexAttribute =
new;
/// Per-vertex: the anchor on the node's axis in node lengths (`xyz`), and the
/// fraction along the piece or the trunk ring (`w`).
pub const ATTRIBUTE_GROWTH_AXIS: MeshVertexAttribute =
new;
/// Per-vertex: the offset from the anchor in units of the piece's scale (`xyz`),
/// and the trunk's unit root-ridge bulge (`w`).
pub const ATTRIBUTE_GROWTH_OFFSET: MeshVertexAttribute =
new;
/// Grow this tree in the vertex shader instead of rebuilding its meshes every
/// frame. Add it to an entity that has [`ProceduralTree`](crate::ProceduralTree)
/// and [`TreeAge`](crate::TreeAge) (and, to make the tree grow,
/// [`Growing`](crate::Growing)).
///
/// The mature tree is built once per change of [`ProceduralTree`](crate::ProceduralTree)
/// and uploaded once; each frame only a few kilobytes of per-node state are
/// written. A tree on this path costs the CPU microseconds per frame instead of
/// the 0.1-0.5 ms the CPU path takes, which makes growing a forest affordable.
///
/// Without this component a tree behaves exactly as before.
///
/// # What differs from the CPU path
///
/// The tree is the same at every age in its overall shape, but it is a
/// deformation of the mature mesh, not a rebuild:
///
/// - **Smoothing** ([`MeshParams::smooth_iterations`](crate::MeshParams::smooth_iterations))
/// is computed once, on the mature mesh, and deformed with the tree; the CPU
/// path smooths every age afresh.
/// - **Ring and side counts are the mature ones.** With
/// [`MeshParams::adaptive_resolution`](crate::MeshParams::adaptive_resolution)
/// a young thin branch keeps the sides of the mature branch.
/// - **Unborn parts have zero size**, instead of being absent; their triangles
/// collapse to a point and draw nothing.
/// - With [`FoliagePlacement::AllBranches`](crate::FoliagePlacement::AllBranches),
/// leaves keep their mature positions along a branch and the first ones appear
/// as it lengthens; the CPU path respaces them.
/// - Tip-cluster leaves that are mirrored away from the trunk
/// ([`FoliagePlacement::TipClusters`](crate::FoliagePlacement::TipClusters))
/// keep the mirroring the mature tree chose.
/// - Leaf normals and the shape of primary bases follow the mature tree.
/// - A growing pointed trunk ends in a flat cap; with smoothing on, the CPU
/// path softens that cap into a point while the tree is young.
/// - The [`Mesh`](bevy::mesh::Mesh) assets on the tree's children, and the
/// bounding box derived from them, are the **mature** tree at every age:
/// picking, physics and frustum culling see the grown size, not the current one.
/// - Growth does not feed motion vectors (temporal anti-aliasing sees a growing
/// branch as still).
///
/// # Platform support
///
/// The per-node state lives in a storage buffer, which WebGL2 does not have. On
/// such a device (and until the renderer is ready) the tree falls back to the
/// CPU path and a warning is logged once.
;
/// Whether this device can grow trees in the vertex shader. [`FloraPlugin`](crate::FloraPlugin)
/// sets it once the renderer is ready, from the device's limits: `true` where
/// the vertex stage can read a storage buffer, `false` on WebGL2. While it is
/// `false`, trees with [`GpuGrowth`] grow on the CPU. Insert it yourself only
/// where there is no renderer (a headless test).
;
/// Set when [`GrowthMaterial`] was registered with the renderer, which only
/// happens if the plugin was added after the renderer's plugins.
pub ;
/// Register what GPU growth needs: the support flag, the material and its
/// shaders when there is a renderer, and the asset types the systems use when
/// there is none.
pub