Files
Emberwild/shaders/foliage.gdshader
Paul Bailey 12f7fd677d M0.5: detailed scenery, mountain/sea-cliff boundary, Godot 4.7
Scenery (all procedural, seeded, no imported assets):
- Terrain shader: grass/dry grass/dirt/sand/rock strata/snow + detail normals
- 5 tree types, faceted mossy rocks, cliff outcrops, sea stacks, bushes,
  logs and stumps, batched as MultiMesh per 48 m cell
- Wind-animated grass and flowers streamed in tiles around the player
- Lake (depth-shaded water with shore foam), ocean to the horizon,
  cloud sky shader, volumetric fog, glow, softer shadows
- Swimming: float at the surface, swim-jump to climb out

World bounds:
- Steep mountain rim with an invisible wall partway up; one side opens to
  a sheer sea cliff with the wall 1 m inside the edge; whole chunk is an
  island so the mesh edge is never visible
- Respawn safety net if the player leaves the walkable area or the map
- Fix: the cliff edge now tracks the wall in the headlands (it used to
  drop away inside the wall, leaving a pit with lake water hanging over it)

Tests: tests/test_boundary.gd (24-direction escape attempt) and
tests/test_terrain_edges.gd (no ground below waterline near the wall).

Upgrades the project to Godot 4.7 (project.godot rewritten by the 4.7
importer, .uid files added) and documents it in the setup guide.
2026-11-03 23:49:39 +00:00

35 lines
1.2 KiB
Plaintext

shader_type spatial;
render_mode cull_back, diffuse_burley;
// Tree canopies and bushes. Colour comes from per-face vertex colours (set by
// proc_mesh.gd), tinted per instance so no two trees are quite the same.
// Wind: slow whole-crown sway growing with height, plus a small leaf flutter.
#include "res://shaders/common.gdshaderinc"
uniform float wind_strength = 0.04;
uniform float flutter = 0.03;
varying vec3 inst_pos;
void vertex() {
inst_pos = MODEL_MATRIX[3].xyz;
float h = max(VERTEX.y - 1.2, 0.0);
float phase = dot(inst_pos.xz, vec2(0.13, 0.17));
float gust = nz(inst_pos.xz * 0.012 + vec2(TIME * 0.02, TIME * 0.013));
vec3 sway = vec3(sin(TIME * 0.9 + phase), 0.0, cos(TIME * 0.7 + phase * 1.3) * 0.6);
sway *= wind_strength * h * (0.4 + gust);
sway += vec3(sin(TIME * 3.7 + dot(VERTEX, vec3(3.1, 1.7, 2.3)) + phase)) * flutter * clamp(VERTEX.y, 0.0, 1.0);
VERTEX += (inverse(MODEL_MATRIX) * vec4(sway, 0.0)).xyz;
}
void fragment() {
float v = nz(inst_pos.xz * 0.045);
vec3 tint = mix(vec3(0.88, 1.0, 0.85), vec3(1.12, 1.04, 0.78), v);
vec3 col = to_linear(COLOR.rgb) * tint;
ALBEDO = col;
ROUGHNESS = 0.85;
SPECULAR = 0.3;
BACKLIGHT = col * 0.5; // light glowing through leaves when backlit
}