Commit graph

1 commit

Author SHA1 Message Date
Admin
294314fb73 render: Kenney's 4,442 static models actually draw — the demo is a place now
THE BLOCKER WAS UPSTREAM OF THE RENDERER: zero of the 4,442 models had a
texture on disk. download_assets.sh extracted only .glb and deleted the zip,
reasoning "GLB is self-contained" — false for Kenney, where every material
points at an external Textures/colormap.png shared across the pack. PNGs are
extracted alongside now, and the resume check REQUIRES a texture, because a
pack of GLBs with no atlas renders white, which is worse than missing.
(The atlases are tiny: 212 textures, 42 KB.)

Static path (model.rs) reuses skin.rs's container/JSON/accessor code rather
than growing a second parser. A static mesh is a skinned one minus joints,
plus one difference: a prop never animates, so each node's world transform is
BAKED into its vertices at load and the model becomes one buffer. Dropping
that bake is exactly how a prop silently renders at the origin, so there is a
test for it. All 4,442 models parse: 1.31M triangles total, 294 average —
comfortably Quest-sized.

Kenney ships TWO conventions, and the second only turned up by looking at a
failure: most packs UV-map into colormap.png, but nature-kit and friends carry
no texture at all and colour each primitive with a material baseColorFactor.
Rather than branch, that factor is baked into the packed vertex's colour lane
and multiplied in the shader (albedo * v_tint) — atlas models carry white,
untextured models get a white 1x1. One shader, both conventions. A model that
DECLARES an atlas but cannot find it stays a hard error; that case really is
broken.

Batching sorts instances by model so equal geometry+texture land adjacent and
accumulate into one draw item: the demo runs 36 instances in 5 draw items,
9,887 triangles. Copies of a prop are free; cost is per distinct model.

The demo picks props BY DESCRIPTION through the asset index (find("pine
tree")), not by hardcoded paths, so it exercises the same path a generated
game takes — and it walks the ranked hits taking the first that loads, so a
pack with a missing atlas yields to the next candidate instead of leaving a
hole. Pillar ring and cone removed; they read as a test harness.

Honest read of the captures: before, coloured cylinders and spheres on a slab
— unmistakably a tech demo. After, a woodland treeline at mixed scale and
species, a suburban house with windows and a teal roof, wooden fences,
textured crates, correctly lit and shadowed. Still imperfect: "boulder"
resolves to nature-kit/cliff_blockCave_rock, a cave-mouth block that reads as
a small building scattered about — a SEARCH-QUALITY gap for the alias owner,
not a render bug.

Washed-out look diagnosed (not fixed, out of scope): it is FOG, not the bake
or the textures. SkyConfig::default()'s density mixes every surface toward the
pale horizon (0.75,0.87,0.96) over a 34-unit camera distance — the far
treeline desaturates toward sky colour while near crates keep their brown. Fix
is either a lower default density or making fog colour follow the sun's
horizon tint so it reads as haze rather than a grey wash.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-03 10:16:07 +02:00