Files
Emberwild/shaders/sky.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

42 lines
1.5 KiB
Plaintext

shader_type sky;
// Gradient sky + sun disc/halo + a static cloud layer projected onto a dome.
// Deliberately no TIME: a time-varying sky forces Godot to rebuild the ambient
// radiance map every frame.
uniform vec3 zenith_col : source_color = vec3(0.24, 0.44, 0.72);
uniform vec3 horizon_col : source_color = vec3(0.72, 0.79, 0.85);
uniform vec3 ground_col : source_color = vec3(0.30, 0.33, 0.32);
uniform vec3 sun_tint : source_color = vec3(1.0, 0.86, 0.62);
uniform sampler2D cloud_tex : filter_linear_mipmap, repeat_enable;
uniform float cloud_cover = 0.5;
uniform float energy = 1.0;
void sky() {
vec3 d = EYEDIR;
float h = d.y;
vec3 col = mix(horizon_col, zenith_col, pow(smoothstep(0.0, 0.6, h), 0.7));
col = mix(col, ground_col, smoothstep(0.0, -0.12, h));
float sd = 0.0;
if (LIGHT0_ENABLED) {
sd = max(dot(d, LIGHT0_DIRECTION), 0.0);
col += sun_tint * pow(sd, 6.0) * 0.35 * (1.0 - smoothstep(0.0, 0.5, h));
col += sun_tint * pow(sd, 64.0) * 0.6;
col += LIGHT0_COLOR * smoothstep(0.9994, 0.9997, sd) * 20.0;
}
if (h > 0.0) {
vec2 uv = d.xz / (h + 0.12);
float c = texture(cloud_tex, uv * 0.08).r * 0.65 + texture(cloud_tex, uv * 0.23 + 0.31).r * 0.35;
float cov = smoothstep(1.0 - cloud_cover, 1.0 - cloud_cover + 0.22, c);
cov *= smoothstep(0.0, 0.18, h);
float shade = smoothstep(0.35, 1.0, c);
vec3 cloud = mix(vec3(1.0), vec3(0.62, 0.66, 0.72), shade * 0.8);
cloud += sun_tint * pow(sd, 4.0) * 0.5;
col = mix(col, cloud, cov * 0.9);
}
COLOR = col * energy;
}