Procedural plants
Bezier spline based Leaves and petals
Tensor product Bezier patches
with m×n control points are used.
"Color coordinates" are added to every control point to get
smoothly colored surface.
Usually convex quadratic 3×3 patches are used.
To get more complex petals e.g. for "bell" 4×3 patches are used.
4×3 = 12 coordinates x, y, z and
red, green, blue colors are set for every control point
in cp array (to get sharp petal 3 degenerate
end points 4, 8, 12 are used).
var m = 4, n = 3;
var cp = new Float32Array([ // petal
0,.3,.2,.6, 0,.6,.3,.6, 0,.3,.2,.6, // x m*n points
0,-.3,-.3,0, 0,0,0,0, 0,.3,.4,0, // y
0,.2,.5,.6, 0,.2,.5,.6, 0,.2,.5,.6, // z
0,0,0,0, 0,0,0,0, 0,0,0,0, // red
0,0,0,0, 0,0,0,0, 0,0,0,0, // green
1,1,1,1, -.8,-.4,.8,1, 1,1,1,1]); // blue
Next Bezier basis functions and regular sm×sn
rectangular mesh are generated.
BezierFunc(m, sm, Bm);
BezierFunc(n, sn, Bn);
splinePatch(m, n, sm, sn2, Bm, Bn, cp, strips, saw);
Note, that sn = 2 sn2 + 1 is odd.
Parameter strips = {0, 1, 2, 3} corresponds to different
color patterning of the patches. saw = true corresponds
to sawtouth patch borders. They are produced by removing
part of border triangles.
Flowers and trees
Flowers are constructed from these patches by rotations
and translations.
rotX( fi, mn, cp1);
rotX_p(fi, off0, off, pt){
E.g. rotX() rotates mn control points and
rotX_p() rotates meshe's points from off0
to off end so on.
See e.g. "flower" source for details.
To make apple garden
- branch is constructed "by hand" of leaves, flowers and stem
by rotations and translations.
- "branch3" is constructed of 4 "branch"s and stem by rotations and translations
- "branch_big" is constructed of 4 "branch3"s and stem by rotations and translations
- and so on to get bigger and bigger tree (I've finished rather arbitrarily :)
- then WebGL instancing is use to get garden (forest)..
Plants animation and morphing
You make e.g. 10 key-frames with serial "ages" and put them all into 2
vertex arrays (the second one is displaced by one frame). Then
mix the two meshes with weight a in the vertex shader
attribute vec3 aPos;
attribute vec3 aPos2;
attribute vec3 aCol;
uniform mat4 mvMatrix;
uniform float a;
varying vec3 color;
void main(void) {
gl_Position = mvMatrix * vec4(mix(aPos, aPos2, a), 1.);
color = aCol;
}
Therefore for 0 < a < 1 you get smooth model morphing
between the two frames. For animation you need some "sorcery"
to prepare a and choose appropriate meshes from 10 key-frames
(the an_off parameter).
var ti = new Date().getTime();
if (ti - Tanim > Tmorph){ Tanim = ti;}
var a = 10*(ti - Tanim) / Tmorph;
var an_off = pi10*Math.floor(a);
a -= Math.floor(a);
gl.uniform1f( aLoc, a );
gl.drawElements(gl.TRIANGLES, pi10, gl.UNSIGNED_INT, 4*an_off);
pi10 is the "size" of one frame.
...
Revolution surfaces
You need NURBS to get circular arcs.
Therefore revolution surfaces (with Bezier generating curves) are used
to avoid petals intersections.
...
Self organized plants
It is difficult (and annoying) to avoid ("by hand")
petals and leaves intersections in complex plant.
Therefore flowers are "charged" and repel each other
(really F = - r / r2 forces,
viscous dynamics and adaptive time steps are used).
See 16 self organized "Electric flowers".
Homogeneous field F = {0, 1, 0} (in the vertical direction)
is added to make umbrella.
One can use similar algorithms to distribute plants on terrains.
Use Van der Waals forces to simulate attraction and make groves.
For Artists. Blender modeler...
I'm using text editor to make simple demos but it is hot handy
for complex models. One can use 3D modeler to make spline
patches. E.g. there are NURBS with Bezier knots in Blender.
Moreover I think that one can use Python scripting to make
procedural plants for Blender (no time to test it yet).
For simple models I don't need any frameworks. I think,
to make something bigger you need choose one (e.g. ThreeJS,
PlayCanvas...).
Unfortunately, I failed to move some of my demos to PlayCanvas.
Don't you like to help me? :)
...
Optimization
To optimize roses one can render outer petals at first
and remove "by hand" invisible inner triangles.
...
Procedural garden
updated 22 Mar 2015