feat(render3d): an aspen quakes, and a tree is no longer bent like a bow

layer_flutter(l, v) gives a scatter layer a per-leaf tremble. The vertex stage offsets
each leaf by a phase taken from its own place on the card, so neighbouring leaves are
never in step, and writes the result out as a varying the fragment stage uses to flash
the leaf's pale underside as it turns - which is the part that reads, since a still
frame of a tremble is a still frame of nothing. One uniform, one varying, no extra pass.

And the sway itself was measured in METRES: hgt * hgt * 0.35 is right for a 40 cm
flower and puts ten metres of sideways into a 14 m trunk, so every tall tree in the
valley stood bent over like a fishing rod. It is a fraction of the model's own height
now - the tip moves a few per cent of the tree whatever the tree is, and the base does
not move at all.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Orkun ÇAKILKAYA 2026-09-19 21:13:42 +03:00
parent 4975c60ac1
commit ab6f310013
47 changed files with 99 additions and 19 deletions

View file

@ -4,6 +4,7 @@ in vec2 v_uv;
in float v_seed;
in vec2 v_rot;
in float v_hull;
in float v_quake; // an aspen leaf turning its pale side up
uniform float u_model_h;
out vec4 o_color;
uniform sampler2D u_diff;
@ -147,6 +148,11 @@ void main() {
if (u_model_h > 2.0) arm.r *= mix(0.5, 1.0, v_hull);
#endif
alb *= u_tint * (0.85 + 0.3 * fract(v_seed * 7.13));
// The quake made visible. A turning aspen leaf shows its pale, almost white underside, so
// the crown does not merely move - it GLITTERS, leaf by leaf, and that is what reads at a
// distance and in a still frame. Toward the viewer is the pale side; away is the face.
if (v_quake > 0.0) alb = mix(alb, alb * 0.55 + vec3(0.42, 0.45, 0.33), min(v_quake * 2.6, 0.75));
else if (v_quake < 0.0) alb *= 1.0 + v_quake * 0.28; // the dark half stays gentle: a crown should shimmer, not flicker
#if defined(FOLIAGE) && !defined(BLADE)
// Per-plant HUE, not only per-plant brightness. The line above varies value by +-15% and
// nothing else, so a stand of one species was one colour at fifteen different exposures -