feat(render3d): rain that leaves something behind

Rain fell and the ground did not change: the weather was a curtain of particles in front
of a dry valley.

u_wet, 0 dry to 1 soaked, does the three things a wet surface does. Darkens the albedo.
Drops the roughness hard - which is what makes a soaked meadow read as soaked rather than
merely dark, because the sky glances off it. And pools: water finds the low places and
flat ground holds what a slope sheds, so the puddle mask is the macro noise the materials
already use gated on slope, and a puddle takes the world's up for its normal rather than
the ground's relief.

It joins the shore's existing wet band rather than fighting it - the same term from a
different cause.

34.1% of the frame changes between dry and soaked. GL 7.1 s either way over 400 frames.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Orkun ÇAKILKAYA 2026-09-19 19:43:29 +03:00
parent 6169cd05b9
commit 031137a5fa
10 changed files with 98 additions and 42 deletions

View file

@ -45,6 +45,8 @@ var ter_smooth: bool = false # generate the analytic test ground instead of a
var ter_far_split: int = 0 # metres: beyond this the terrain takes its cheap far path (R3D_TFAR)
var ter_far_band: int = 0 # half-width of the near/far blend (R3D_TBAND)
var ter_snow_line: int = 0
# 0 dry .. 1 soaked. The game sets it from the weather and lets it dry out.
var ter_wet: int = 0
var ter_tex: words = null # 11 material textures (see terrain_bind)
var ter_ox: int = 0 # world x/z of the terrain centre (float bits)
var ter_oz: int = 0
@ -483,6 +485,7 @@ function terrain_bind_prog(p: int) -> void {
u_f(gpu_uniform(p, "u_half"), fi(TERRAIN_HALF))
u_f(gpu_uniform(p, "u_texel"), fr(1, TERRAIN_RES))
u_f(gpu_uniform(p, "u_snow_line"), ter_snow_line)
u_f(gpu_uniform(p, "u_wet"), ter_wet)
var lake = fl(-100000.0)
if ter_lake_ex != 0 { lake = ter_lake_level }
u_f(gpu_uniform(p, "u_lake_level"), lake)