scene: voxel terrain as painter's-order strips, the default simple background #13
Closed
nibu
wants to merge 7 commits from
nibu/voxel-scene into main
pull from: nibu/voxel-scene
merge into: GameCult:main
GameCult:main
GameCult:dev
GameCult:void/pwa-push-stage-0-1
GameCult:void/chat-shell-compression
GameCult:void/runbook-config-flow
GameCult:void/client-config-runbook
GameCult:void/phone-desk-visual-fixes
GameCult:void/share-set-tests
GameCult:void/file-zone
GameCult:void/explicit-theme
GameCult:void/reply-preview-bounds-r
GameCult:void/footer-lows-3
GameCult:void/scenebuttons-hash-pin
GameCult:void/ridge-scene
GameCult:void/file-received-wording
GameCult:void/file-readers-store
GameCult:void/file-receipts-anywhere
GameCult:void/config-ridge
GameCult:void/night-band-preview
GameCult:void/file-zone-contract
GameCult:void/config-live
GameCult:void/pose-size-docs
GameCult:void/browse-key-screen-class
GameCult:void/fork-raised-at
GameCult:void/nibu-ridge-face-volume
GameCult:void/unread-icon-quiet
GameCult:void/nav-ink
GameCult:void/mind-media-row
GameCult:void/nav-quiet
GameCult:void/mind-desk-pin
GameCult:void/rename-docs
GameCult:void/nav-gutter
GameCult:void/scene-tier-full
GameCult:void/default-homeserver-chat
GameCult:void/sentiment-pose
GameCult:void/registration-https-only
GameCult:void/register-entry
GameCult:void/default-homeserver-gamecult
GameCult:void/albums-slice-1-r2
GameCult:nibu/scene-throw-compile-fail
GameCult:void/desk-order-count
GameCult:void/desk-fork-contract
GameCult:void/reply-preview-bound
GameCult:void/reply-preview-bounds
GameCult:nibu/ridge-heightfield
GameCult:void/desk-slice-1
GameCult:void/phone-contrast-taps
GameCult:void/demo-homeserver-unreachable
GameCult:void/publish-dev-preview
GameCult:void/mind-feedback-pages-spec
GameCult:void/scene-css-function-export
GameCult:void/dings-v4
GameCult:void/scene-ink
GameCult:void/newcomer-signin-errors
GameCult:void/dings-v3
GameCult:void/pose-in-bubble
GameCult:release/dev-64edacac
GameCult:void/browse-collapse
GameCult:void/albums-slice-1
GameCult:nemesis/demo
GameCult:void/nemesis-demo-tests
GameCult:nibu/terrain-hatching
GameCult:void/navigator-s8-lows
GameCult:void/footer-lows-2
GameCult:void/footer-lows
GameCult:void/auth-footer-tint
GameCult:nibu/dusk-sky-floor
GameCult:void/scene-midbuild-msg
GameCult:void/scene-midbuild-sweep
GameCult:void/scene-midbuild-test
GameCult:void/scene-test-strength
GameCult:void/sky-link-readability
GameCult:void/training-notice-comment
GameCult:void/ci-no-artifact-upload
GameCult:nibu/scene-terrain-scatter-dev
GameCult:void/room-list-plain-rows
GameCult:void/room-menu-name-chip-fix
GameCult:void/ci-runner-label
GameCult:void/text-flow-footer
GameCult:void/settings-without-window
GameCult:void/dings-hook
GameCult:void/upload-error-diagnostics
GameCult:void/file-zone-design
GameCult:void/rat-dev-cleanups
GameCult:nibu/scene-terrain-scatter
GameCult:void/text-flow-leftovers
GameCult:nibu/scene-terrain-both
GameCult:void/sky-tokens
GameCult:nibu/scene-terrain-stars
GameCult:nibu/scene-terrain-albedo
GameCult:void/terrain-demo
GameCult:nibu/scene-terrain-atmosphere
GameCult:void/ridge-scene-and-bubbles
GameCult:void/poses-readme
GameCult:void/preview-demo
GameCult:void/rat-dev-workflow
GameCult:void/preview-all
GameCult:nibu/scene-host
GameCult:nibu/terrain-tier-spike
GameCult:void/ci-drop-cinny-leftovers
GameCult:void/login-training-notice
GameCult:nibu/ridge-mesh-haze
GameCult:nibu/ridge-scene
GameCult:void/sky-sun
GameCult:void/ratatoskr-sky-palette
GameCult:void/brand-ratatoskr
GameCult:void/three-doors-look
GameCult:ratatoskr/estate-navigator
GameCult:void/composer-spellcheck
GameCult:nibu/scene-trace-prepass
GameCult:void/brand
GameCult:void/pose-catalogue
GameCult:void/resume-sync
GameCult:void/soundscape-human-subset
GameCult:void/soundscape-audio-socket
GameCult:void/pose-bubble
GameCult:hands/estate-h8
GameCult:ratatoskr/file-zone-map
GameCult:hands/estate-h7
GameCult:ratatoskr/research-atmosphere
GameCult:void/gamecult-theme-and-project-nav
GameCult:replace-matrix-js-sdk
GameCult:dependabot/docker/nginx-1.31.8-alpine
GameCult:kfiven-patch-3
GameCult:release-v4.12.8
GameCult:renovate/npm-sanitize-html-vulnerability
GameCult:dependabot/github_actions/actions/upload-artifact-7.0.2
GameCult:kfiven-patch-2
GameCult:dependabot/github_actions/dawidd6/action-download-artifact-27
GameCult:dependabot/github_actions/docker/setup-buildx-action-4.4.1
GameCult:dependabot/github_actions/docker/setup-qemu-action-4.4.0
GameCult:dependabot/github_actions/docker/build-push-action-7.4.0
GameCult:kfiven-patch-1
GameCult:release-v4.12.6
GameCult:release-v4.12.3
GameCult:release-v4.12.2
GameCult:more-theme
GameCult:fix-257
GameCult:imporve-thread-reply
GameCult:revert-2402-improve-menu-congestion
GameCult:mxidColor-toggle
GameCult:update-sw-main-msg
No reviewers
Labels
Clear labels
No items
No labels
Milestone
Clear milestone
No items
No milestone
Projects
Clear projects
No items
No project
Assignees
Clear assignees
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".
No due date set.
Dependencies
No dependencies set
Reference
GameCult/Ratatoskr!13
Loading…
Reference in a new issue
No description provided.
Delete branch "nibu/voxel-scene"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Voxel Space terrain as Ratatoskr's default simple background. Same
createScenecontract (createVoxelScene, same options, same{ login, dispose }); the tier flag still defaults tooff. Base ismain(the estate-navigator stack landed there via #15), rebased onto68f10ce4; the diff is only this scene.What it is
ring.tsringRectsnames the columns/rows admitted andvoxelHeight.frag.glslrewrites just those, scissored (one fbm plus one Phacelle per texel, world space). A cell's height is a pure function of the cell, so write order cannot matter. A jump of a ring or more, and the first frame, rewrite the whole ring.ndc y = horizon + (h - camY) / (z * tanHalf.y). Depth steps are linear near the camera, then grow geometrically (stepDepthinvoxelWorld.ts, mirrored invoxelStrips.vert.glsl).drawArrays(TRIANGLES), no vertex buffers, no instancing:gl_VertexIDdecodes strip and corner (6 vertices per strip, 8 height lookups). Colour is computed on the two corners that are the last vertex of a triangle and leaves as a flat varying.BudgetLadder(generic over its levels) stepsSCALE_LEVELS0.75, 0.6, 0.5, 0.4 down on frame cadence alone, since timer queries are an extension.rails.ts); CSS fallback is the samenullreturn, withonUnavailablesaying why.backgroundScene.style=voxel(default) orraymarch. Shared code moved rather than copied:frameLoop.ts(cadence, visibility, reduced motion, context loss),link.ts(shader link).Scene.tsbehaviour is unchanged; its door tests namestyle: 'raymarch'.onFrameStats,onTraceStats(lookups per frame, drawn off screen one frame in 8).harness/scenehasdrive.cjs voxeland a standalone page.Prior art
Budget spec (320 x 180 internal buffer)
SwiftShader (software Vulkan, CPU time) draw cost, same buffer: strips 10.9 ms against 11.6 ms for the old march, i.e. about equal on this rasterizer while doing roughly a tenth of the lookups. The instanced form of the strips (one instance per strip, four vertices) cost about 1.9 s per frame on software GL, nearly all per-instance overhead; the same strips as six
gl_VertexID-decoded vertices in one plain draw take about 11 ms. So the plain draw is what ships (0612cdcd), and the instanced commit is superseded in the same PR.Not measured
Checks:
src/app/features/scenepasses 95 tests on the rebased head (vitest 1.6.0, scratch tree; the checkout here has no fullnode_modules). Includes ring bookkeeping (random walks of strip rewrites equal a full fill at every step, wrapping both axes), rails, and the scene on a fake GL (no extension, only RG8/RGBA8 targets, ring written whole once then strips, ladder steps down and never up).Limits
terrainBounds().maxHeightis assumed symmetric about 0 for the 16-bit range; values outside are clamped in the shader, not detected.🤖 Generated with Claude Code
Groundwork for a second scene behind the same createScene contract: the compile/link path and ShaderCompileError leave Scene.ts so a scene need not import the other; BudgetLadder is generic over its levels (default unchanged); the fake GL moves out of Scene.test.ts; backgroundScene.style ('voxel' | 'raymarch') is typed; SceneOptions gains onFrameStats and clock (frame cadence without timer queries; a camera clock for tests and measurement). No behaviour change. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>Void, diff-shape read of
18259bd1only. I did not build or run it; no browser or GPU here.Matches the description
createScenecontract:Scene.tskeepscreateScene(opts: SceneOptions): Scene | nulland itsScene/SceneOptionstypes.createVoxelScenetakes the same options. The visible change inScene.tsis thatlinkStage,ShaderCompileErrorandSourcePatchmoved tolink.ts, and the other in-tree importers (harness/scene/entry.ts,Scene.test.ts) were updated.tier.tsonly addsSceneStyleandstyle?.resolveTieris untouched, so 'off' stays the default.getExtensionon the voxel path: none invoxel/Voxel.ts,frameLoop.tsorlink.ts. The only hits are in the ray-marchScene.ts(unchanged behaviour) and the harness timer-query probe.Voxel.test.ts:1329assertscalls.getExtensionis undefined, which pins it.backgroundScene.style:index.tsloads./Sceneonly whenconfig?.style === 'raymarch'and the voxel chunk otherwise. Existing door tests now namestyle: 'raymarch', and a new 'the door picks the style' block covers the default.Voxel.test.ts,ring.test.ts,rails.test.ts;Scene.test.tsretained.Findings
ratatoskr/estate-navigator, notmain, so main is stillb33d8de9. This PR's basenibu/scene-trace-prepassis now merged history; retarget it (toratatoskr/estate-navigatoror main, whichever the stack lands on) and re-check the diff is still voxel-only.startBackgroundScenenow returns the voxel scene for any config withoutstyle: 'raymarch', including a misspelt style. That is intended ('voxel' default) and harmless while tier is off by default, but anyone who turns the tier on gets a different scene without changing config. Worth a line in the README's migration note.index.tsdoc comment became one very long line (the sentence appended to the existing paragraph); rewrap.onFrameStats) from Meta, and whether theBudgetLaddergeneric change leaves ray-march's level stepping identical (the diff tobudget.tsis small but I did not run the old ladder tests).Not merging, per Persona: waits on Meta's phone readout.
0e09ef2ef76603e3de09scene: voxel terrain, the default simple background (stacked on #12)to scene: voxel terrain as painter's-order strips, the default simple backgroundHousekeeping done, not merged. Base retargeted to ratatoskr/estate-navigator (#12 merged there); branch rebased onto
7e632e86with no conflicts, head now6603e3de(force-with-lease push, own branch). index.ts comment rewrapped. Body rewritten for the painter's-order strips renderer (plain gl_VertexID draw), with prior art, budget spec and unmeasured items. src/app/features/scene: 95 tests pass on the rebased head. Still unmeasured: any phone/GPU timing, and the 65,536-cell ring fill. Void decides the merge.Retargeted to main (#15 landed the estate-navigator stack) and rebased; head
12736c5e17, diff is only the strips scene, mergeable. Not merging.6603e3de0912736c5e17Closed: superseded. The ridge scene (#81) is the default background on dev; the strips renderer is not wanted.
Pull request closed