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

@ -0,0 +1,15 @@
bump: minor
type: feat
An aspen leaf hangs on a flattened stalk and turns in air a spruce never feels, and the
kit had no way to say so. `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. The flash is the part
that reads - a still frame of a tremble is a still frame of nothing. One uniform, one
varying, no extra pass, and every other layer leaves it at zero.
Also fixes the sway itself, which 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, so the tip moves a few per cent of the tree whatever the tree is and the base does
not move at all.

View file

@ -19,6 +19,7 @@ property Layer {
imp: Impostor, imp: Impostor,
foliage: bool = false, foliage: bool = false,
wind: int = 0, # float bits wind: int = 0, # float bits
flutter: int = 0, # float bits; per-leaf tremble (aspen), 0 = none
tint: words, tint: words,
inst: words, # INST_FLOATS per instance inst: words, # INST_FLOATS per instance
count: int = 0, count: int = 0,
@ -128,6 +129,11 @@ function model_cross_card() -> Model {
} }
# A card layer: crossed cards carrying a single-tile atlas baked from `scan`. # A card layer: crossed cards carrying a single-tile atlas baked from `scan`.
# An aspen leaf hangs on a flattened stalk and turns in air nothing else feels. Give the
# layer a flutter and its leaves tremble and flash their pale undersides; everything else
# leaves it at zero. It is per layer rather than per instance because a species quakes or
# it does not.
function layer_flutter(l: Layer, v: int) -> void { l.flutter = v }
function layer_cards(scan: Model, cap: int, wind: int, cull: int) -> Layer { function layer_cards(scan: Model, cap: int, wind: int, cull: int) -> Layer {
let l = layer_new(model_cross_card(), cap, true, wind, F_ZERO, cull) let l = layer_new(model_cross_card(), cap, true, wind, F_ZERO, cull)
l.card = true l.card = true
@ -473,6 +479,7 @@ function impostor_bake(model: Model, tiles: int, tw: int, th: int) -> Impostor {
u_mat4(gpu_uniform(bake, "u_view"), view) u_mat4(gpu_uniform(bake, "u_view"), view)
u_mat4(gpu_uniform(bake, "u_proj"), proj) u_mat4(gpu_uniform(bake, "u_proj"), proj)
u_f(gpu_uniform(bake, "u_wind"), F_ZERO) u_f(gpu_uniform(bake, "u_wind"), F_ZERO)
u_f(gpu_uniform(bake, "u_flutter"), F_ZERO)
gpu_viewport(t * tw, 0, tw, th) gpu_viewport(t * tw, 0, tw, th)
for i in 0 .. len(model.prims) { for i in 0 .. len(model.prims) {
let pr = model.prims[i] let pr = model.prims[i]
@ -1032,6 +1039,7 @@ function layer_draw_model(l: Layer, model: Model, vb: int, cnt: int, card: bool,
if l.grounded { terrain_bind_height(p) } if l.grounded { terrain_bind_height(p) }
u_f(gpu_uniform(p, "u_time"), r3d_time) u_f(gpu_uniform(p, "u_time"), r3d_time)
u_f(gpu_uniform(p, "u_wind"), l.wind) u_f(gpu_uniform(p, "u_wind"), l.wind)
u_f(gpu_uniform(p, "u_flutter"), l.flutter)
var mh = F_ZERO var mh = F_ZERO
if not card and l.foliage { mh = model.height } if not card and l.foliage { mh = model.height }
u_f(gpu_uniform(p, "u_model_h"), mh) u_f(gpu_uniform(p, "u_model_h"), mh)
@ -1154,6 +1162,7 @@ function layer_draw_depth(l: Layer, model: Model, vb: int, cnt: int) -> void {
if l.grounded { terrain_bind_height(p) } if l.grounded { terrain_bind_height(p) }
u_f(gpu_uniform(p, "u_time"), r3d_time) u_f(gpu_uniform(p, "u_time"), r3d_time)
u_f(gpu_uniform(p, "u_wind"), l.wind) u_f(gpu_uniform(p, "u_wind"), l.wind)
u_f(gpu_uniform(p, "u_flutter"), l.flutter)
u_f(gpu_uniform(p, "u_model_h"), model.height) u_f(gpu_uniform(p, "u_model_h"), model.height)
u_mat4(gpu_uniform(p, "u_view"), cam_view) u_mat4(gpu_uniform(p, "u_view"), cam_view)
u_mat4(gpu_uniform(p, "u_proj"), cam_proj) u_mat4(gpu_uniform(p, "u_proj"), cam_proj)
@ -1298,6 +1307,7 @@ function carpet_bake(layers: []Layer, count: int, tile: int, res: int) -> int {
u_mat4(gpu_uniform(bake, "u_view"), view) u_mat4(gpu_uniform(bake, "u_view"), view)
u_mat4(gpu_uniform(bake, "u_proj"), proj) u_mat4(gpu_uniform(bake, "u_proj"), proj)
u_f(gpu_uniform(bake, "u_wind"), F_ZERO) u_f(gpu_uniform(bake, "u_wind"), F_ZERO)
u_f(gpu_uniform(bake, "u_flutter"), F_ZERO)
u_f(gpu_uniform(bake, "u_time"), F_ZERO) u_f(gpu_uniform(bake, "u_time"), F_ZERO)
for li in 0 .. len(layers) { for li in 0 .. len(layers) {
let l = layers[li] let l = layers[li]

View file

@ -38,6 +38,7 @@ out vec2 v_uv[];
out float v_seed[]; out float v_seed[];
out vec2 v_rot[]; out vec2 v_rot[];
out float v_hull[]; out float v_hull[];
out float v_quake[]; // grass does not quake; written so model.frag can read it
const float CELL = 16.0; const float CELL = 16.0;
float hash1(vec2 p) { return fract(sin(dot(p, vec2(127.1, 311.7))) * 43758.5453123); } float hash1(vec2 p) { return fract(sin(dot(p, vec2(127.1, 311.7))) * 43758.5453123); }
@ -153,6 +154,7 @@ void main() {
v_seed[o] = seed; v_seed[o] = seed;
v_rot[o] = vec2(s, c_); v_rot[o] = vec2(s, c_);
v_hull[o] = hull; v_hull[o] = hull;
v_quake[o] = 0.0;
} }
} }
for (int q = 0; q < ROWS - 1; q++) { for (int q = 0; q < ROWS - 1; q++) {

View file

@ -41,6 +41,7 @@ out vec2 v_uv;
out float v_seed; out float v_seed;
out vec2 v_rot; out vec2 v_rot;
out float v_hull; out float v_hull;
out float v_quake; // only aspens quake; written so model.frag can read it
const float CELL = 16.0; const float CELL = 16.0;
float hash1(vec2 p) { return fract(sin(dot(p, vec2(127.1, 311.7))) * 43758.5453123); } float hash1(vec2 p) { return fract(sin(dot(p, vec2(127.1, 311.7))) * 43758.5453123); }
@ -67,7 +68,7 @@ float heightSmooth(sampler2D tex, vec2 uv) {
return (texture(tex, vec2(o0.x, o0.y)).r * s0.x + texture(tex, vec2(o1.x, o0.y)).r * s1.x) * s0.y return (texture(tex, vec2(o0.x, o0.y)).r * s0.x + texture(tex, vec2(o1.x, o0.y)).r * s1.x) * s0.y
+ (texture(tex, vec2(o0.x, o1.y)).r * s0.x + texture(tex, vec2(o1.x, o1.y)).r * s1.x) * s1.y; + (texture(tex, vec2(o0.x, o1.y)).r * s0.x + texture(tex, vec2(o1.x, o1.y)).r * s1.x) * s1.y;
} }
void cull() { gl_Position = vec4(0.0, 0.0, 2.0, 1.0); v_wpos = vec3(0.0); v_nrm = vec3(0.0, 1.0, 0.0); v_uv = vec2(0.0); v_seed = 0.0; v_rot = vec2(0.0, 1.0); v_hull = 1.0; } void cull() { gl_Position = vec4(0.0, 0.0, 2.0, 1.0); v_wpos = vec3(0.0); v_nrm = vec3(0.0, 1.0, 0.0); v_uv = vec2(0.0); v_seed = 0.0; v_rot = vec2(0.0, 1.0); v_hull = 1.0; v_quake = 0.0; }
void main() { void main() {
#ifdef TILES #ifdef TILES
@ -198,6 +199,7 @@ void main() {
v_uv = far ? vec2(a_uv.x, 0.45 + 0.2 * a_uv.y) : a_uv; v_uv = far ? vec2(a_uv.x, 0.45 + 0.2 * a_uv.y) : a_uv;
v_seed = seed; v_seed = seed;
v_rot = vec2(s, c_); v_rot = vec2(s, c_);
v_quake = 0.0;
v_hull = (dist > 2.0 || far || (u_dbg & 2) != 0) ? -1.0 : 1.0; // no back-face flip, no rounding past arm's reach v_hull = (dist > 2.0 || far || (u_dbg & 2) != 0) ? -1.0 : 1.0; // no back-face flip, no rounding past arm's reach
gl_Position = u_proj * u_view * vec4(w, 1.0); gl_Position = u_proj * u_view * vec4(w, 1.0);
} }

View file

@ -4,6 +4,7 @@ in vec2 v_uv;
in float v_seed; in float v_seed;
in vec2 v_rot; in vec2 v_rot;
in float v_hull; in float v_hull;
in float v_quake; // an aspen leaf turning its pale side up
uniform float u_model_h; uniform float u_model_h;
out vec4 o_color; out vec4 o_color;
uniform sampler2D u_diff; 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); if (u_model_h > 2.0) arm.r *= mix(0.5, 1.0, v_hull);
#endif #endif
alb *= u_tint * (0.85 + 0.3 * fract(v_seed * 7.13)); 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) #if defined(FOLIAGE) && !defined(BLADE)
// Per-plant HUE, not only per-plant brightness. The line above varies value by +-15% and // 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 - // nothing else, so a stand of one species was one colour at fifteen different exposures -

View file

@ -54,8 +54,15 @@ out vec2 v_rot;
// have been shaded since SpeedTree; without it a card crown reads as frosted. // have been shaded since SpeedTree; without it a card crown reads as frosted.
uniform float u_model_h; // the model's height (m), 0 = not a crown uniform float u_model_h; // the model's height (m), 0 = not a crown
out float v_hull; // 0 at the crown's axis .. 1 at its rim out float v_hull; // 0 at the crown's axis .. 1 at its rim
// An aspen leaf hangs on a flattened stalk, so it twists in air a conifer does not feel at
// all. u_flutter is per layer: 0 for everything else, and the quake is written out as a
// varying so the fragment stage can flash the leaf's pale underside as it turns - which is
// the part you actually SEE. A still frame of a tremble is a still frame of nothing.
uniform float u_flutter;
out float v_quake;
void main() { void main() {
float s = i_rot.x, c = i_rot.y; float s = i_rot.x, c = i_rot.y;
v_quake = 0.0;
vec3 p = a_pos * i_pos.w; vec3 p = a_pos * i_pos.w;
#ifdef CARD #ifdef CARD
p = vec3(p.x * u_card_w, p.y * u_card_h, p.z * u_card_w); p = vec3(p.x * u_card_w, p.y * u_card_h, p.z * u_card_w);
@ -81,8 +88,28 @@ void main() {
// read at the tree's own place in the world, so a gust crosses the grass and goes on into // read at the tree's own place in the world, so a gust crosses the grass and goes on into
// the trees. `stiff` is 0.35 because a bole resists what a blade cannot. // the trees. `stiff` is 0.35 because a bole resists what a blade cannot.
float sway = windSway(i_pos.xz, u_time, ph, 0.35) * u_wind * i_rot.w; float sway = windSway(i_pos.xz, u_time, ph, 0.35) * u_wind * i_rot.w;
p.x += sway * hgt * hgt * 0.35; // The bend is a FRACTION OF THE TREE, not a number of metres. `hgt * hgt` in metres is
p.z += sway * hgt * hgt * 0.15 * cos(ph * 0.7); // fine for a 40 cm flower and ruinous for a 14 m aspen - it put ten metres of sideways
// into a trunk and bent it over like a fishing rod, which is what standing under one and
// looking up finally showed. Normalised, the tip moves a few per cent of the tree's own
// height whatever the tree is, and the base does not move at all.
float th = max(u_model_h * i_pos.w, 0.001);
float hn = (u_model_h > 2.0) ? clamp(hgt / th, 0.0, 1.0) : min(hgt, 1.0);
float reach = (u_model_h > 2.0) ? th * 0.22 : 0.35;
p.x += sway * hn * hn * reach;
p.z += sway * hn * hn * reach * 0.43 * cos(ph * 0.7);
if (u_flutter > 0.0) {
// per-leaf, not per-tree: the phase comes from the vertex's own place on the card, so
// neighbouring leaves are never in step - a crown that trembles as one block reads as
// the whole tree shivering.
float qp = u_time * 8.5 + a_pos.x * 11.3 + a_pos.z * 9.7 + a_pos.y * 4.1 + i_rot.z * 6.2831;
float q = sin(qp) * 0.65 + sin(qp * 1.73 + 1.1) * 0.35;
float amp = u_flutter * (0.40 + 0.60 * windGust(i_pos.xz, u_time)) * smoothstep(0.0, 1.2, hgt);
p.x += q * amp * 0.10;
p.y += q * amp * 0.05;
p.z += cos(qp * 0.9) * amp * 0.10;
v_quake = q * amp;
}
#endif #endif
v_hull = 1.0; v_hull = 1.0;
if (u_model_h > 2.0) { if (u_model_h > 2.0) {

View file

@ -21,6 +21,7 @@ out vec2 v_uv;
out float v_seed; out float v_seed;
out vec2 v_rot; out vec2 v_rot;
out float v_hull; out float v_hull;
out float v_quake; // only aspens quake; written so model.frag can read it
void main() { void main() {
mat4 m = u_model; mat4 m = u_model;
if (u_skinned > 0.5) { if (u_skinned > 0.5) {
@ -43,6 +44,7 @@ void main() {
v_seed = 0.0701; v_seed = 0.0701;
v_rot = vec2(0.0, 1.0); v_rot = vec2(0.0, 1.0);
v_hull = 1.0; v_hull = 1.0;
v_quake = 0.0;
#ifdef SHADOW_PASS #ifdef SHADOW_PASS
gl_Position = u_light_vp * w; gl_Position = u_light_vp * w;
#else #else

View file

@ -1076,7 +1076,7 @@ T 4d4fa91b u_shadow 7
T 4d4fa91b u_tershadow 8 T 4d4fa91b u_tershadow 8
T 4d4fa91b u_ts_height 9 T 4d4fa91b u_ts_height 9
P 9dce3246 model.vert bake.frag P 9dce3246 model.vert bake.frag
B 9dce3246 vert 0 232 B 9dce3246 vert 0 236
U 9dce3246 vert u_view 0 mat4 1 0 U 9dce3246 vert u_view 0 mat4 1 0
U 9dce3246 vert u_proj 64 mat4 1 0 U 9dce3246 vert u_proj 64 mat4 1 0
U 9dce3246 vert u_light_vp 128 mat4 1 0 U 9dce3246 vert u_light_vp 128 mat4 1 0
@ -1088,6 +1088,7 @@ U 9dce3246 vert u_ground 208 float 1 0
U 9dce3246 vert u_ts_origin 216 vec2 1 0 U 9dce3246 vert u_ts_origin 216 vec2 1 0
U 9dce3246 vert u_ts_half 224 float 1 0 U 9dce3246 vert u_ts_half 224 float 1 0
U 9dce3246 vert u_model_h 228 float 1 0 U 9dce3246 vert u_model_h 228 float 1 0
U 9dce3246 vert u_flutter 232 float 1 0
I 9dce3246 i_rot 4 vec4 I 9dce3246 i_rot 4 vec4
I 9dce3246 a_pos 0 vec3 I 9dce3246 a_pos 0 vec3
I 9dce3246 i_pos 3 vec4 I 9dce3246 i_pos 3 vec4
@ -1137,7 +1138,7 @@ T 9dce3246 u_shadow 7
T 9dce3246 u_tershadow 8 T 9dce3246 u_tershadow 8
T 9dce3246 u_ts_height 9 T 9dce3246 u_ts_height 9
P 439a2253 model.vert bake.frag #define CARD; P 439a2253 model.vert bake.frag #define CARD;
B 439a2253 vert 0 232 B 439a2253 vert 0 236
U 439a2253 vert u_view 0 mat4 1 0 U 439a2253 vert u_view 0 mat4 1 0
U 439a2253 vert u_proj 64 mat4 1 0 U 439a2253 vert u_proj 64 mat4 1 0
U 439a2253 vert u_light_vp 128 mat4 1 0 U 439a2253 vert u_light_vp 128 mat4 1 0
@ -1149,6 +1150,7 @@ U 439a2253 vert u_ground 208 float 1 0
U 439a2253 vert u_ts_origin 216 vec2 1 0 U 439a2253 vert u_ts_origin 216 vec2 1 0
U 439a2253 vert u_ts_half 224 float 1 0 U 439a2253 vert u_ts_half 224 float 1 0
U 439a2253 vert u_model_h 228 float 1 0 U 439a2253 vert u_model_h 228 float 1 0
U 439a2253 vert u_flutter 232 float 1 0
I 439a2253 i_rot 4 vec4 I 439a2253 i_rot 4 vec4
I 439a2253 a_pos 0 vec3 I 439a2253 a_pos 0 vec3
I 439a2253 i_pos 3 vec4 I 439a2253 i_pos 3 vec4
@ -1198,7 +1200,7 @@ T 439a2253 u_shadow 7
T 439a2253 u_tershadow 8 T 439a2253 u_tershadow 8
T 439a2253 u_ts_height 9 T 439a2253 u_ts_height 9
P 86f427b0 model.vert bake.frag #define FLOWER; P 86f427b0 model.vert bake.frag #define FLOWER;
B 86f427b0 vert 0 232 B 86f427b0 vert 0 236
U 86f427b0 vert u_view 0 mat4 1 0 U 86f427b0 vert u_view 0 mat4 1 0
U 86f427b0 vert u_proj 64 mat4 1 0 U 86f427b0 vert u_proj 64 mat4 1 0
U 86f427b0 vert u_light_vp 128 mat4 1 0 U 86f427b0 vert u_light_vp 128 mat4 1 0
@ -1210,6 +1212,7 @@ U 86f427b0 vert u_ground 208 float 1 0
U 86f427b0 vert u_ts_origin 216 vec2 1 0 U 86f427b0 vert u_ts_origin 216 vec2 1 0
U 86f427b0 vert u_ts_half 224 float 1 0 U 86f427b0 vert u_ts_half 224 float 1 0
U 86f427b0 vert u_model_h 228 float 1 0 U 86f427b0 vert u_model_h 228 float 1 0
U 86f427b0 vert u_flutter 232 float 1 0
I 86f427b0 i_rot 4 vec4 I 86f427b0 i_rot 4 vec4
I 86f427b0 a_pos 0 vec3 I 86f427b0 a_pos 0 vec3
I 86f427b0 i_pos 3 vec4 I 86f427b0 i_pos 3 vec4
@ -1259,7 +1262,7 @@ T 86f427b0 u_shadow 7
T 86f427b0 u_tershadow 8 T 86f427b0 u_tershadow 8
T 86f427b0 u_ts_height 9 T 86f427b0 u_ts_height 9
P bfa15301 model.vert depth.frag #define FOLIAGE;#define WIND;#define ALPHA_TEST; P bfa15301 model.vert depth.frag #define FOLIAGE;#define WIND;#define ALPHA_TEST;
B bfa15301 vert 0 232 B bfa15301 vert 0 236
U bfa15301 vert u_view 0 mat4 1 0 U bfa15301 vert u_view 0 mat4 1 0
U bfa15301 vert u_proj 64 mat4 1 0 U bfa15301 vert u_proj 64 mat4 1 0
U bfa15301 vert u_light_vp 128 mat4 1 0 U bfa15301 vert u_light_vp 128 mat4 1 0
@ -1271,6 +1274,7 @@ U bfa15301 vert u_ground 208 float 1 0
U bfa15301 vert u_ts_origin 216 vec2 1 0 U bfa15301 vert u_ts_origin 216 vec2 1 0
U bfa15301 vert u_ts_half 224 float 1 0 U bfa15301 vert u_ts_half 224 float 1 0
U bfa15301 vert u_model_h 228 float 1 0 U bfa15301 vert u_model_h 228 float 1 0
U bfa15301 vert u_flutter 232 float 1 0
I bfa15301 i_rot 4 vec4 I bfa15301 i_rot 4 vec4
I bfa15301 a_pos 0 vec3 I bfa15301 a_pos 0 vec3
I bfa15301 i_pos 3 vec4 I bfa15301 i_pos 3 vec4
@ -1319,7 +1323,7 @@ T bfa15301 u_shadow 6
T bfa15301 u_tershadow 7 T bfa15301 u_tershadow 7
T bfa15301 u_ts_height 8 T bfa15301 u_ts_height 8
P 01089da8 model.vert model.frag P 01089da8 model.vert model.frag
B 01089da8 vert 0 232 B 01089da8 vert 0 236
U 01089da8 vert u_view 0 mat4 1 0 U 01089da8 vert u_view 0 mat4 1 0
U 01089da8 vert u_proj 64 mat4 1 0 U 01089da8 vert u_proj 64 mat4 1 0
U 01089da8 vert u_light_vp 128 mat4 1 0 U 01089da8 vert u_light_vp 128 mat4 1 0
@ -1331,6 +1335,7 @@ U 01089da8 vert u_ground 208 float 1 0
U 01089da8 vert u_ts_origin 216 vec2 1 0 U 01089da8 vert u_ts_origin 216 vec2 1 0
U 01089da8 vert u_ts_half 224 float 1 0 U 01089da8 vert u_ts_half 224 float 1 0
U 01089da8 vert u_model_h 228 float 1 0 U 01089da8 vert u_model_h 228 float 1 0
U 01089da8 vert u_flutter 232 float 1 0
I 01089da8 i_rot 4 vec4 I 01089da8 i_rot 4 vec4
I 01089da8 a_pos 0 vec3 I 01089da8 a_pos 0 vec3
I 01089da8 i_pos 3 vec4 I 01089da8 i_pos 3 vec4
@ -1386,7 +1391,7 @@ T 01089da8 u_shadow 8
T 01089da8 u_tershadow 9 T 01089da8 u_tershadow 9
T 01089da8 u_ts_height 10 T 01089da8 u_ts_height 10
P 254e7887 model.vert model.frag #define CARD;#define CHEAP; P 254e7887 model.vert model.frag #define CARD;#define CHEAP;
B 254e7887 vert 0 232 B 254e7887 vert 0 236
U 254e7887 vert u_view 0 mat4 1 0 U 254e7887 vert u_view 0 mat4 1 0
U 254e7887 vert u_proj 64 mat4 1 0 U 254e7887 vert u_proj 64 mat4 1 0
U 254e7887 vert u_light_vp 128 mat4 1 0 U 254e7887 vert u_light_vp 128 mat4 1 0
@ -1398,6 +1403,7 @@ U 254e7887 vert u_ground 208 float 1 0
U 254e7887 vert u_ts_origin 216 vec2 1 0 U 254e7887 vert u_ts_origin 216 vec2 1 0
U 254e7887 vert u_ts_half 224 float 1 0 U 254e7887 vert u_ts_half 224 float 1 0
U 254e7887 vert u_model_h 228 float 1 0 U 254e7887 vert u_model_h 228 float 1 0
U 254e7887 vert u_flutter 232 float 1 0
I 254e7887 i_rot 4 vec4 I 254e7887 i_rot 4 vec4
I 254e7887 a_pos 0 vec3 I 254e7887 a_pos 0 vec3
I 254e7887 i_pos 3 vec4 I 254e7887 i_pos 3 vec4
@ -1454,7 +1460,7 @@ T 254e7887 u_shadow 8
T 254e7887 u_tershadow 9 T 254e7887 u_tershadow 9
T 254e7887 u_ts_height 10 T 254e7887 u_ts_height 10
P 1ce5c5d1 model.vert model.frag #define FOLIAGE;#define WIND;#define ALPHA_TEST; P 1ce5c5d1 model.vert model.frag #define FOLIAGE;#define WIND;#define ALPHA_TEST;
B 1ce5c5d1 vert 0 232 B 1ce5c5d1 vert 0 236
U 1ce5c5d1 vert u_view 0 mat4 1 0 U 1ce5c5d1 vert u_view 0 mat4 1 0
U 1ce5c5d1 vert u_proj 64 mat4 1 0 U 1ce5c5d1 vert u_proj 64 mat4 1 0
U 1ce5c5d1 vert u_light_vp 128 mat4 1 0 U 1ce5c5d1 vert u_light_vp 128 mat4 1 0
@ -1466,6 +1472,7 @@ U 1ce5c5d1 vert u_ground 208 float 1 0
U 1ce5c5d1 vert u_ts_origin 216 vec2 1 0 U 1ce5c5d1 vert u_ts_origin 216 vec2 1 0
U 1ce5c5d1 vert u_ts_half 224 float 1 0 U 1ce5c5d1 vert u_ts_half 224 float 1 0
U 1ce5c5d1 vert u_model_h 228 float 1 0 U 1ce5c5d1 vert u_model_h 228 float 1 0
U 1ce5c5d1 vert u_flutter 232 float 1 0
I 1ce5c5d1 i_rot 4 vec4 I 1ce5c5d1 i_rot 4 vec4
I 1ce5c5d1 a_pos 0 vec3 I 1ce5c5d1 a_pos 0 vec3
I 1ce5c5d1 i_pos 3 vec4 I 1ce5c5d1 i_pos 3 vec4
@ -1521,7 +1528,7 @@ T 1ce5c5d1 u_shadow 8
T 1ce5c5d1 u_tershadow 9 T 1ce5c5d1 u_tershadow 9
T 1ce5c5d1 u_ts_height 10 T 1ce5c5d1 u_ts_height 10
P f4a2b586 model.vert model.frag #define FOLIAGE;#define WIND;#define BLADE; P f4a2b586 model.vert model.frag #define FOLIAGE;#define WIND;#define BLADE;
B f4a2b586 vert 0 248 B f4a2b586 vert 0 252
U f4a2b586 vert u_view 0 mat4 1 0 U f4a2b586 vert u_view 0 mat4 1 0
U f4a2b586 vert u_proj 64 mat4 1 0 U f4a2b586 vert u_proj 64 mat4 1 0
U f4a2b586 vert u_light_vp 128 mat4 1 0 U f4a2b586 vert u_light_vp 128 mat4 1 0
@ -1535,6 +1542,7 @@ U f4a2b586 vert u_ground 224 float 1 0
U f4a2b586 vert u_ts_origin 232 vec2 1 0 U f4a2b586 vert u_ts_origin 232 vec2 1 0
U f4a2b586 vert u_ts_half 240 float 1 0 U f4a2b586 vert u_ts_half 240 float 1 0
U f4a2b586 vert u_model_h 244 float 1 0 U f4a2b586 vert u_model_h 244 float 1 0
U f4a2b586 vert u_flutter 248 float 1 0
I f4a2b586 i_rot 4 vec4 I f4a2b586 i_rot 4 vec4
I f4a2b586 a_pos 0 vec3 I f4a2b586 a_pos 0 vec3
I f4a2b586 i_pos 3 vec4 I f4a2b586 i_pos 3 vec4
@ -1592,7 +1600,7 @@ T f4a2b586 u_shadow 8
T f4a2b586 u_tershadow 9 T f4a2b586 u_tershadow 9
T f4a2b586 u_ts_height 10 T f4a2b586 u_ts_height 10
P b4587cd4 model.vert model.frag #define FOLIAGE;#define WIND;#define CARD; P b4587cd4 model.vert model.frag #define FOLIAGE;#define WIND;#define CARD;
B b4587cd4 vert 0 232 B b4587cd4 vert 0 236
U b4587cd4 vert u_view 0 mat4 1 0 U b4587cd4 vert u_view 0 mat4 1 0
U b4587cd4 vert u_proj 64 mat4 1 0 U b4587cd4 vert u_proj 64 mat4 1 0
U b4587cd4 vert u_light_vp 128 mat4 1 0 U b4587cd4 vert u_light_vp 128 mat4 1 0
@ -1604,6 +1612,7 @@ U b4587cd4 vert u_ground 208 float 1 0
U b4587cd4 vert u_ts_origin 216 vec2 1 0 U b4587cd4 vert u_ts_origin 216 vec2 1 0
U b4587cd4 vert u_ts_half 224 float 1 0 U b4587cd4 vert u_ts_half 224 float 1 0
U b4587cd4 vert u_model_h 228 float 1 0 U b4587cd4 vert u_model_h 228 float 1 0
U b4587cd4 vert u_flutter 232 float 1 0
I b4587cd4 i_rot 4 vec4 I b4587cd4 i_rot 4 vec4
I b4587cd4 a_pos 0 vec3 I b4587cd4 a_pos 0 vec3
I b4587cd4 i_pos 3 vec4 I b4587cd4 i_pos 3 vec4
@ -1660,7 +1669,7 @@ T b4587cd4 u_shadow 8
T b4587cd4 u_tershadow 9 T b4587cd4 u_tershadow 9
T b4587cd4 u_ts_height 10 T b4587cd4 u_ts_height 10
P 4dda406a model.vert model.frag #define FOLIAGE;#define WIND;#define EQ_PASS; P 4dda406a model.vert model.frag #define FOLIAGE;#define WIND;#define EQ_PASS;
B 4dda406a vert 0 232 B 4dda406a vert 0 236
U 4dda406a vert u_view 0 mat4 1 0 U 4dda406a vert u_view 0 mat4 1 0
U 4dda406a vert u_proj 64 mat4 1 0 U 4dda406a vert u_proj 64 mat4 1 0
U 4dda406a vert u_light_vp 128 mat4 1 0 U 4dda406a vert u_light_vp 128 mat4 1 0
@ -1672,6 +1681,7 @@ U 4dda406a vert u_ground 208 float 1 0
U 4dda406a vert u_ts_origin 216 vec2 1 0 U 4dda406a vert u_ts_origin 216 vec2 1 0
U 4dda406a vert u_ts_half 224 float 1 0 U 4dda406a vert u_ts_half 224 float 1 0
U 4dda406a vert u_model_h 228 float 1 0 U 4dda406a vert u_model_h 228 float 1 0
U 4dda406a vert u_flutter 232 float 1 0
I 4dda406a i_rot 4 vec4 I 4dda406a i_rot 4 vec4
I 4dda406a a_pos 0 vec3 I 4dda406a a_pos 0 vec3
I 4dda406a i_pos 3 vec4 I 4dda406a i_pos 3 vec4
@ -1727,7 +1737,7 @@ T 4dda406a u_shadow 8
T 4dda406a u_tershadow 9 T 4dda406a u_tershadow 9
T 4dda406a u_ts_height 10 T 4dda406a u_ts_height 10
P 3b183d8f model.vert model.frag #define FOLIAGE;#define WIND;#define FLOWER; P 3b183d8f model.vert model.frag #define FOLIAGE;#define WIND;#define FLOWER;
B 3b183d8f vert 0 232 B 3b183d8f vert 0 236
U 3b183d8f vert u_view 0 mat4 1 0 U 3b183d8f vert u_view 0 mat4 1 0
U 3b183d8f vert u_proj 64 mat4 1 0 U 3b183d8f vert u_proj 64 mat4 1 0
U 3b183d8f vert u_light_vp 128 mat4 1 0 U 3b183d8f vert u_light_vp 128 mat4 1 0
@ -1739,6 +1749,7 @@ U 3b183d8f vert u_ground 208 float 1 0
U 3b183d8f vert u_ts_origin 216 vec2 1 0 U 3b183d8f vert u_ts_origin 216 vec2 1 0
U 3b183d8f vert u_ts_half 224 float 1 0 U 3b183d8f vert u_ts_half 224 float 1 0
U 3b183d8f vert u_model_h 228 float 1 0 U 3b183d8f vert u_model_h 228 float 1 0
U 3b183d8f vert u_flutter 232 float 1 0
I 3b183d8f i_rot 4 vec4 I 3b183d8f i_rot 4 vec4
I 3b183d8f a_pos 0 vec3 I 3b183d8f a_pos 0 vec3
I 3b183d8f i_pos 3 vec4 I 3b183d8f i_pos 3 vec4
@ -1794,7 +1805,7 @@ T 3b183d8f u_shadow 8
T 3b183d8f u_tershadow 9 T 3b183d8f u_tershadow 9
T 3b183d8f u_ts_height 10 T 3b183d8f u_ts_height 10
P 79b77ed9 model.vert model.frag #define SHADOW_PASS;#define WIND;#define CARD; P 79b77ed9 model.vert model.frag #define SHADOW_PASS;#define WIND;#define CARD;
B 79b77ed9 vert 0 232 B 79b77ed9 vert 0 236
U 79b77ed9 vert u_view 0 mat4 1 0 U 79b77ed9 vert u_view 0 mat4 1 0
U 79b77ed9 vert u_proj 64 mat4 1 0 U 79b77ed9 vert u_proj 64 mat4 1 0
U 79b77ed9 vert u_light_vp 128 mat4 1 0 U 79b77ed9 vert u_light_vp 128 mat4 1 0
@ -1806,6 +1817,7 @@ U 79b77ed9 vert u_ground 208 float 1 0
U 79b77ed9 vert u_ts_origin 216 vec2 1 0 U 79b77ed9 vert u_ts_origin 216 vec2 1 0
U 79b77ed9 vert u_ts_half 224 float 1 0 U 79b77ed9 vert u_ts_half 224 float 1 0
U 79b77ed9 vert u_model_h 228 float 1 0 U 79b77ed9 vert u_model_h 228 float 1 0
U 79b77ed9 vert u_flutter 232 float 1 0
I 79b77ed9 i_rot 4 vec4 I 79b77ed9 i_rot 4 vec4
I 79b77ed9 a_pos 0 vec3 I 79b77ed9 a_pos 0 vec3
I 79b77ed9 i_pos 3 vec4 I 79b77ed9 i_pos 3 vec4
@ -1862,7 +1874,7 @@ T 79b77ed9 u_shadow 8
T 79b77ed9 u_tershadow 9 T 79b77ed9 u_tershadow 9
T 79b77ed9 u_ts_height 10 T 79b77ed9 u_ts_height 10
P b9fc2041 model.vert model.frag #define WIND; P b9fc2041 model.vert model.frag #define WIND;
B b9fc2041 vert 0 232 B b9fc2041 vert 0 236
U b9fc2041 vert u_view 0 mat4 1 0 U b9fc2041 vert u_view 0 mat4 1 0
U b9fc2041 vert u_proj 64 mat4 1 0 U b9fc2041 vert u_proj 64 mat4 1 0
U b9fc2041 vert u_light_vp 128 mat4 1 0 U b9fc2041 vert u_light_vp 128 mat4 1 0
@ -1874,6 +1886,7 @@ U b9fc2041 vert u_ground 208 float 1 0
U b9fc2041 vert u_ts_origin 216 vec2 1 0 U b9fc2041 vert u_ts_origin 216 vec2 1 0
U b9fc2041 vert u_ts_half 224 float 1 0 U b9fc2041 vert u_ts_half 224 float 1 0
U b9fc2041 vert u_model_h 228 float 1 0 U b9fc2041 vert u_model_h 228 float 1 0
U b9fc2041 vert u_flutter 232 float 1 0
I b9fc2041 i_rot 4 vec4 I b9fc2041 i_rot 4 vec4
I b9fc2041 a_pos 0 vec3 I b9fc2041 a_pos 0 vec3
I b9fc2041 i_pos 3 vec4 I b9fc2041 i_pos 3 vec4
@ -1929,7 +1942,7 @@ T b9fc2041 u_shadow 8
T b9fc2041 u_tershadow 9 T b9fc2041 u_tershadow 9
T b9fc2041 u_ts_height 10 T b9fc2041 u_ts_height 10
P f34dce08 model.vert shadow.frag #define SHADOW_PASS; P f34dce08 model.vert shadow.frag #define SHADOW_PASS;
B f34dce08 vert 0 232 B f34dce08 vert 0 236
U f34dce08 vert u_view 0 mat4 1 0 U f34dce08 vert u_view 0 mat4 1 0
U f34dce08 vert u_proj 64 mat4 1 0 U f34dce08 vert u_proj 64 mat4 1 0
U f34dce08 vert u_light_vp 128 mat4 1 0 U f34dce08 vert u_light_vp 128 mat4 1 0
@ -1941,6 +1954,7 @@ U f34dce08 vert u_ground 208 float 1 0
U f34dce08 vert u_ts_origin 216 vec2 1 0 U f34dce08 vert u_ts_origin 216 vec2 1 0
U f34dce08 vert u_ts_half 224 float 1 0 U f34dce08 vert u_ts_half 224 float 1 0
U f34dce08 vert u_model_h 228 float 1 0 U f34dce08 vert u_model_h 228 float 1 0
U f34dce08 vert u_flutter 232 float 1 0
I f34dce08 i_rot 4 vec4 I f34dce08 i_rot 4 vec4
I f34dce08 a_pos 0 vec3 I f34dce08 a_pos 0 vec3
I f34dce08 i_pos 3 vec4 I f34dce08 i_pos 3 vec4
@ -1989,7 +2003,7 @@ T f34dce08 u_shadow 6
T f34dce08 u_tershadow 7 T f34dce08 u_tershadow 7
T f34dce08 u_ts_height 8 T f34dce08 u_ts_height 8
P 512004a1 model.vert shadow.frag #define SHADOW_PASS;#define WIND; P 512004a1 model.vert shadow.frag #define SHADOW_PASS;#define WIND;
B 512004a1 vert 0 232 B 512004a1 vert 0 236
U 512004a1 vert u_view 0 mat4 1 0 U 512004a1 vert u_view 0 mat4 1 0
U 512004a1 vert u_proj 64 mat4 1 0 U 512004a1 vert u_proj 64 mat4 1 0
U 512004a1 vert u_light_vp 128 mat4 1 0 U 512004a1 vert u_light_vp 128 mat4 1 0
@ -2001,6 +2015,7 @@ U 512004a1 vert u_ground 208 float 1 0
U 512004a1 vert u_ts_origin 216 vec2 1 0 U 512004a1 vert u_ts_origin 216 vec2 1 0
U 512004a1 vert u_ts_half 224 float 1 0 U 512004a1 vert u_ts_half 224 float 1 0
U 512004a1 vert u_model_h 228 float 1 0 U 512004a1 vert u_model_h 228 float 1 0
U 512004a1 vert u_flutter 232 float 1 0
I 512004a1 i_rot 4 vec4 I 512004a1 i_rot 4 vec4
I 512004a1 a_pos 0 vec3 I 512004a1 a_pos 0 vec3
I 512004a1 i_pos 3 vec4 I 512004a1 i_pos 3 vec4
@ -2049,7 +2064,7 @@ T 512004a1 u_shadow 6
T 512004a1 u_tershadow 7 T 512004a1 u_tershadow 7
T 512004a1 u_ts_height 8 T 512004a1 u_ts_height 8
P b964507f model.vert shadow.frag #define SHADOW_PASS;#define WIND;#define ALPHA_TEST; P b964507f model.vert shadow.frag #define SHADOW_PASS;#define WIND;#define ALPHA_TEST;
B b964507f vert 0 232 B b964507f vert 0 236
U b964507f vert u_view 0 mat4 1 0 U b964507f vert u_view 0 mat4 1 0
U b964507f vert u_proj 64 mat4 1 0 U b964507f vert u_proj 64 mat4 1 0
U b964507f vert u_light_vp 128 mat4 1 0 U b964507f vert u_light_vp 128 mat4 1 0
@ -2061,6 +2076,7 @@ U b964507f vert u_ground 208 float 1 0
U b964507f vert u_ts_origin 216 vec2 1 0 U b964507f vert u_ts_origin 216 vec2 1 0
U b964507f vert u_ts_half 224 float 1 0 U b964507f vert u_ts_half 224 float 1 0
U b964507f vert u_model_h 228 float 1 0 U b964507f vert u_model_h 228 float 1 0
U b964507f vert u_flutter 232 float 1 0
I b964507f i_rot 4 vec4 I b964507f i_rot 4 vec4
I b964507f a_pos 0 vec3 I b964507f a_pos 0 vec3
I b964507f i_pos 3 vec4 I b964507f i_pos 3 vec4