Skip to content

feat(snowy-village): add Snowbound Crossing - #79

Merged
hoainho merged 5 commits into
mainfrom
feat/snowy-village-showcase-hyper3d
Sep 29, 2026
Merged

hoainho merged 5 commits into
mainfrom
feat/snowy-village-showcase-hyper3d

Conversation

@hoainho

@hoainho hoainho commented Sep 28, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

  • Demo id / title: snowy-village / Snowbound Crossing — Mini Game
  • Migrates the playable winter village into the current lazy-loaded catalog with the original scene models, animations, snowfall, smoke, fire, day/night controls, and gate interaction. The fixed gate frame stays collidable while the two leaves open.
  • Runtime mesh labels use procedural-img2threejs_mesh_* except the two requested IDs, which remain exactly hyper3d_mesh_297a4bb9-ceab-4c9f-940d-fd78631b1cec:0 and hyper3d_mesh_f5ae0d3a-9839-44ac-a100-c4761df806a5:0.
  • Hyper3D provenance remains in Snowy metadata. Other demos and shared sponsor content are unchanged.

Performance root cause and fix

  • Chrome CPU profiles showed the snowfall update repeatedly raycasting flakes against every triangle in the house mesh: the baseline profile sampled intersectTriangle for 1.15 s and getVertexPosition for 0.71 s over 3.04 s. The particles do not cast shadows; their house collision raycasts were the CPU hotspot.
  • Added a per-house BVH with first-hit-only exact raycasts. It preserves the original triangle intersections and snow effect while removing the repeated full-geometry traversal.
  • The sun shadow map was 4096x4096 over a 320-unit light-space box (about 7.8 cm per texel). It is now 2048x2048 over ±16 units with a tighter far plane; this uses 4x fewer shadow texels and about 5x denser world-space shadow coverage, reducing shimmer without changing shadow casters; the separate daytime-lighting retune is documented below.

Verification

  • At commit a0163aa, a clean-clone npm run build passed. The current follow-up passes npx tsc --noEmit, but this worktree Vite build fails with ENOENT while statting public/baseline/girl-character.glb (listed as 0 B here). Donate and iPhone Duo integrity checks pass.
  • Browser production preview loaded the role assets, rendered the scene, and opened the gate with E; no page errors.
  • After-fix production movement sample: 120 frames, mean 13.34 ms, p95 14.9 ms, max 15.3 ms, zero frames above 33 ms. Main-thread TaskDuration increased 0.418 s over 1.97 s; BVH raycast sample was 2.4 ms. The before/after profile removes the former triangle-intersection hot path.
  • Prewarm smoke passed: nine core roles, 957 decoded images, campfire failure isolation/retry, and both mesh-name exceptions.

Contributor checklist

  • Reference-image rights: overview image carried from the Snowy source project; an explicit license statement is not recorded.
  • Generated via the img2threejs skill (version not recorded in source; Snowy provenance names Hyper3D).
  • npm run build passes locally in a clean clone.
  • Rendered-browser screenshot attachment; overview image is linked below, but no separate browser capture is uploaded.
  • Only touched the demo folder, reference image, and registry; this PR also changes shared Viewer camera-orbit plumbing and Snowy control styling to preserve the authored interaction.
  • Registry entry is complete and status is final.

Screenshot

Snowy Village overview image

One incidental case-insensitive triPo substring remains only inside the opaque base64 PNG payload in native/data/gate.mjs. The image bytes and hash are unchanged; there is no Tripo metadata, node label, or provenance in the Snowy feature.

Gate collision and daylight follow-up

  • Open passage is measured in normalized gate-local coordinates from both hinges and the panel seam. The entire player collision box plus a 4 cm clearance must fit before only the gate-frame and leaf colliders are bypassed; other scene colliders remain solid.
  • Live noon smoke: the player crossed the fully open gate from interior to exterior; approaches at both posts (z=1.998 and z=3.548) remained blocked at x≈-4.715. After closing, both leaves returned to approximately 0 radians and a 2 s outward movement attempt from x=-2.39 was blocked. Browser error capture was empty.
  • Daylight is softer and warmer: hemisphere intensity 1.05→0.62, sun 1.65→1.15, environment intensity 0.82→0.40; SUN_DAY is #FFD796 and the directional-light target is at the house center. The noon browser capture retains roof/snow detail and warmer wood tones.
  • npx tsc --noEmit and git diff --check passed.

@hoainho
hoainho merged commit 1782ddd into main Sep 29, 2026
1 check failed
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