scene: voxel terrain as painter's-order strips, the default simple background #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.6603e3de0912736c5e17View command line instructions
Checkout
From your project repository, check out a new branch and test the changes.Merge
Merge the changes and update on Forgejo.Warning: The "Autodetect manual merge" setting is not enabled for this repository, you will have to mark this pull request as manually merged afterwards.