render3d/foliage: a small plant is occluded by the sward it stands in, so it no longer glows at night
The user saw kit grass, ferns and flowers lit up at night. Nothing was emissive and every layer draw binds the scene's lighting; what differed was occlusion. At night the sky's light is nearly all the light, and it is scaled by ambient occlusion: the meadow's blades are heavily occluded near the ground, while a kit plant's own AO map knows nothing of the grass around it, so it took the full sky. By day the sun hides the difference. model.vert hands on each vertex's height above the model's base (v_lh), and a non-blade FOLIAGE plant under 2 m scales its AO from 0.35 at the ground to 1 at 0.9 m. Crowns and the blades are untouched. Measured in the lab (R3D_AT=tree, same binary, old and new SPIR-V): the fern against the meadow beside it was 2.05x at 23:00 and 1.66x at 13:00; now 1.58x and 1.60x - the same relation by night as by day. The flowers' brightest tenth at night 78 -> 52. The noon frame moves 8.4% of pixels past 8 (the fern and flower bases a little darker; run-to-run noise is part of that). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
3a2d594626
commit
6a82b4928b
27 changed files with 11 additions and 0 deletions
|
|
@ -6,6 +6,9 @@ in vec2 v_rot;
|
||||||
in float v_hull;
|
in float v_hull;
|
||||||
in float v_quake; // an aspen leaf turning its pale side up
|
in float v_quake; // an aspen leaf turning its pale side up
|
||||||
in float v_near; // 0 in the camera's face, 1 past arm's length (NEAR_FADE)
|
in float v_near; // 0 in the camera's face, 1 past arm's length (NEAR_FADE)
|
||||||
|
#if defined(FOLIAGE) && !defined(BLADE)
|
||||||
|
in float v_lh; // height above the model's base (model.vert)
|
||||||
|
#endif
|
||||||
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;
|
||||||
|
|
@ -208,6 +211,12 @@ 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));
|
||||||
|
#if defined(FOLIAGE) && !defined(BLADE)
|
||||||
|
// A fern or a clump stands IN the sward, and its low leaves see the sky through it no more than the
|
||||||
|
// blades beside them do. Its own occlusion map knows nothing of the grass around it, so by night -
|
||||||
|
// when the sky's light is nearly all the light there is - it stood out lit against the meadow.
|
||||||
|
if (u_model_h <= 2.0) arm.r *= mix(0.35, 1.0, smoothstep(0.0, 0.9, v_lh));
|
||||||
|
#endif
|
||||||
// The quake made visible. A turning aspen leaf shows its pale, almost white underside, so
|
// 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
|
// 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.
|
// distance and in a still frame. Toward the viewer is the pale side; away is the face.
|
||||||
|
|
|
||||||
|
|
@ -61,6 +61,7 @@ out float v_hull; // 0 at the crown's axis .. 1 at its rim
|
||||||
uniform float u_flutter;
|
uniform float u_flutter;
|
||||||
out float v_near; // 0 in the camera's face, 1 past arm's length (NEAR_FADE)
|
out float v_near; // 0 in the camera's face, 1 past arm's length (NEAR_FADE)
|
||||||
out float v_quake;
|
out float v_quake;
|
||||||
|
out float v_lh; // height above the model's base (m): a small plant's ground occlusion
|
||||||
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;
|
v_quake = 0.0;
|
||||||
|
|
@ -68,6 +69,7 @@ void main() {
|
||||||
#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);
|
||||||
#endif
|
#endif
|
||||||
|
v_lh = max(p.y, 0.0);
|
||||||
vec3 n = a_nrm;
|
vec3 n = a_nrm;
|
||||||
#ifdef BLADE
|
#ifdef BLADE
|
||||||
// distant blades: wider so a thinner field keeps its coverage, lit like the ground
|
// distant blades: wider so a thinner field keeps its coverage, lit like the ground
|
||||||
|
|
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Add table
Add a link
Reference in a new issue