Skip to content

feat(visuals): reflective water, stone house, meadow foliage, cloudy sky#1

Open
proggeramlug wants to merge 9 commits into
mainfrom
feat/visual-overhaul
Open

feat(visuals): reflective water, stone house, meadow foliage, cloudy sky#1
proggeramlug wants to merge 9 commits into
mainfrom
feat/visual-overhaul

Conversation

@proggeramlug

Copy link
Copy Markdown
Contributor

A full visual overhaul of the arena on Windows — from a white-box/flat-teal scene to a framed outdoor environment.

Water

  • Analytic sky + sun reflection with Schlick Fresnel over a refracted riverbed (scene_color sampled + wave-normal distortion) and Beer-Lambert depth tint, replacing the flat teal pane. The planar-reflection probe renders black for this immediate-mode game and the procedural sky never lands in env_tex, so the reflection is computed analytically in-shader.

Building

  • The 25 placeholder _gizmo_box walls/steps are baked into one stone-textured house.glb (makeHouse, world-space verts, drawn once at the origin) with a wooden roof + fascia. The boxes stay as invisible physics colliders.

Procedural textures

  • Seamless stone / wood / metal / floor + grass-blade, wildflower, and a richer seamless grass (tools/png.ts, new periodic fbmp/noise2p). Props build unconditionally now — the Unvanquished tex-tech vendor source is no longer required (it fell back to solid grey, i.e. the white box).

Foliage

  • ~300 wind-swaying grass tufts + wildflowers scattered over the terrain (hash-jittered, skipping river/house/spawn), plus a perimeter treeline framing the arena and hiding the terrain edge. All alpha-cutout so they sway via the engine's foliage path.

Terrain / lighting / atmosphere

  • Seamless grass tiling, larger tile, 512px texture.
  • Golden-hour sun, lower ambient + stronger SSAO for contrast, sky-matched aerial fog.
  • Player model now faces its movement direction (fixes turning the wrong way when strafing/backpedaling).

Tooling

  • tools/shot.ps1 (build + foreground + screenshot), tools/geisterhand-smoketest.ps1, tools/preview-grass.ts (texture previewer). .gitignore extended for Windows build/run artifacts.

Depends on

Ralph Kuepper added 9 commits June 15, 2026 23:12
Major visual overhaul (Windows):
- Water: analytic sky+sun reflection + refracted riverbed (Fresnel,
  Beer-Lambert depth tint) replacing the flat teal pane.
- House: the 25 placeholder building boxes are baked into one
  stone-textured house.glb (makeHouse) with a wooden roof; the boxes
  stay as invisible physics colliders.
- Procedural textures: seamless stone/wood/metal/floor + grass-blade,
  wildflower, and a richer seamless grass (png.ts). Props now build
  unconditionally since vendor tex-tech is no longer required.
- Foliage: ~300 wind-swaying grass tufts + wildflowers scattered over
  the terrain, plus a perimeter treeline framing the arena.
- Terrain: seamless grass tiling, larger tile, 512px texture.
- Lighting/atmosphere: golden-hour sun, lower ambient + stronger SSAO
  for contrast, sky-matched aerial fog.
- Player facing follows movement direction (fixes wrong-way turning).
- Tooling: shot.ps1 (build+screenshot), geisterhand smoke test,
  preview-grass.ts texture previewer.
Completes the BRDF surface inputs — the scene shader already consumed normal
maps (derivative TBN, no tangents needed) + Toksvig spec-AA, but the shooter
supplied none, so every surface shaded flat with constant roughness.

- png.ts: heightToNormal() derives a seamless tangent-space normal map from an
  albedo's luminance (Sobel height field), encoded to the engine's decode.
- Terrain grass + stone/wood/floor/bark/metal now carry a derived normal map,
  wired via each material's normalTexture so the loader treats them as linear,
  mip-variance-baked normals. Surfaces now catch the directional sun with
  per-texel relief (masonry blocks/mortar read dimensional at grazing angles)
  instead of flat paint.
- Verified the cached-model color pipeline is already correct (shader
  srgb-decodes albedo via srgb_to_linear_v), so no gamma change was needed.
…adows

The ambient was crushed to 22% so the warm key sun dominated; outdoors the sky
dome is a major ambient source. Measured against the house's shadowed (sky-lit)
walls: 0.45 lifts shadowed surfaces with cooler sky-colour fill while keeping
sun/shadow contrast (auto-exposure absorbs the overall-brightness delta, so this
shifts the ambient:direct ratio, not the exposure).
…/wood/floor/bark

Completes the BRDF surface inputs (albedo + normal + roughness). roughnessMR()
derives a glTF MR map from albedo luminance — recessed mortar/grooves/seams read
matte, faces a touch glossier; all dielectric. Wired via MR_FOR ->
metallicRoughnessTexture (the shader already supports per-texel G=roughness,
B=metallic gated on metal_rough.z).
Blend the planar-reflection probe (now rendering the actual mirrored trees/house,
see engine) over the analytic sky dome by the probe's alpha, perturbed by the
wave normal. Foliage reflections read dappled (cutout gaps show sky) which is
physically correct.
A toggleable (VERIFY_CALIB) sphere grid drawn through the scene shader for
objective exposure/BRDF verification: grey albedos 0.18/0.5/0.9 + a roughness
sweep + a metallic sweep. Confirms the linear/AgX exposure chain (sensible grey
progression, no crushed/blown tones), IBL ambient sky-fill on shadowed sides,
and IBL specular reflections on the metallic row. Off by default.
… + canopy

- Player facing: always orient to the camera yaw (PUBG/aim-style) instead of
  the movement direction while moving — strafing/backpedalling no longer points
  the body away from where the camera looks.
- Trees: new pushTrunk() builds a tapered, root-flared, slightly-leaning, non-
  circular trunk (was a perfect round pole). Canopy rebuilt from overlapping
  leaf-card clumps + ragged outliers instead of fixed-height rings, for a
  rounder, less boxy silhouette.
- SUN_DIR now points TO the sun (y>0). The engine treats light/sun direction as
  direction-to-sun in scene diffuse (max(dot(N,light_dir),0)), shadow cascade fit
  (light at center+light_dir*d), and sky LUT (mu_s=sun.y). The old downward
  vector (y=-0.30) put the sun below the horizon → flat ambient-only ground +
  grazing 'weird' shadows. Removed the compensating -sun_dir negations in the
  water glint + analytic sky-reflection sun disc.
- Player + enemy facing: updateModelAnimation takes a SINGLE rot_y angle now;
  the shooter still passed (sin,cos) so cos was dropped and the body rotated by
  sin(camYaw) rad (~stuck looking left). Player rot_y = pi/2 - camYaw (faces the
  camera look dir); enemies rot_y = atan2(-dz,dx) toward the player.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant