Repository navigation
The live passes in a browser as natively: every pass at most eight storage buffers, merged.rs's live half gone - #69
Merged
Merged
Conversation
…orage buffers, merged.rs's live half gone The three passes over a browser's eight, rearranged; the browser's layout is now the native one, a layout a pass. - post (13): the view modes are passes of their own before it, not run in the lit picture (view_raw, view_hdr, view_sample); an HDR snapshot in a view mode is now that signal. - compose (11): the upscaler's state of each sample (Flicker, Lock) is a pass of its own after it, track. - dtemporal (10): the surfaces' compact copy (sb) is written by refl, which reads each sample whole anyway. - The sample's parts are read apart (sample_diffuse, _specular, _emission). - merged.rs: the slabs, the offsets' uniform and the live source's rewrite are gone; the kernel's outputs the passes read start at multiples of 256 bytes in its merged buffer (@align(256); the struct's size rounded to it), so a page binds those ranges. A unit test holds every pass to eight, and a view in the merged layout checks it as it starts. Checks: cargo test 125 passed. render-identity against the build before, native: 3 of 190 outputs differ by rounding (particles-motion-repose 277 pixels, at most ~3e-6 nits on dark ones; wind-pivot-sway-live, voxel-cut-body-push ~3e-5 relative); THREERT_MERGED=1: 3 (at most 7.5e-5 nits on values of 1 to 4). View modes 1-8: every PNG identical (the material tests). tools/web-hello.ts in Chrome: pass. Cost +0.18 ms (Bistro, 1440p at 0.375, alternated: track 0.27 less compose's 0.08; the surfaces' copy in refl +0.02). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Step 2 of the plan for the live passes' layout, after #68. Three passes bound more than a browser's eight storage buffers per stage, so the browser needed its own merged layout: a rewrite of the live source and slabs indexed through an offsets uniform. This PR rearranges those three so every pass binds at most eight. The browser now uses the native layout, one per pass. Tier R1/R2: pictures change only by rounding (see the checks below).
The change
post(13 storage buffers): the view modes become passes of their own before it (view_raw,view_hdr,view_sample). A frame showing the lit picture does not run them. The per-pass profile times an empty pass for each, so its timestamps keepPASSES' order.compose(11): the upscaler's per-sample state (Flicker,Lock) moves to a pass of its own after it,track.dtemporal(10): the surfaces' compact copy (sb) is now written byrefl, which reads each sample whole anyway. A separate pass for it cost 0.18 ms, because it read the samples a second time.sample_diffuse,sample_specular,sample_emission), so a pass binds the resolved reflection only if it takes the specular part.merged.rs's live half is gone: the slabs, the offsets uniform and the rewrite of the live source.@align(256), with the struct's size rounded to match), so a page can bind those ranges directly.every_pass_fits_a_browser) holds every pass to eight, and a view in the merged layout checks the same when it starts.Merge gate
cargo test --releaseparticles-motion-repose(277 pixels, at most ~3e-6 nits, all on dark pixels),wind-pivot-sway-liveandvoxel-cut-body-push(~3e-5 relative)THREERT_MERGED=1skinning-shared-pose-split-live,volume-grid-uniform-live,wind-pivot-sway-live(at most 7.5e-5 nits, on values of 1 to 4)materialtests,THREERT_VIEW_MODE)tools/web-hello.tsin Chrome on this GPUcompose/tracksplit (track0.27 ms,compose0.08 ms less). Bistro, 1440p at 0.375, alternated: the passes after the trace 6.00–6.08 → 6.19–6.24 ms. Thesbcopy inreflcosts +0.02; the view passes cost nothing in the lit picture.The rounding differences come from code that moved: the same expressions, split or merged differently, compile to arithmetic that differs in the last bits, and a temporal test carries those bits along. The largest absolute difference is 7.5e-5 nits.
ROADMAP § 1a records the step.
🤖 Generated with Claude Code
Note
Medium Risk
Touches the full live rendering pipeline and browser binding path; identity checks show tiny rounding drift and a small perf hit, but view modes stay byte-identical.
Overview
Rearranges the live post chain so every compute pass binds at most eight storage buffers, letting the browser use the same per-pass bind layouts as native and removing
merged.rs's live shader rewrite (slabs, offsets uniform, merged bind group).Shader / pass split: view-mode visualization moves out of
postintoview_raw,view_hdr, andview_sample(skipped in the normal lit frame). Upscaling flicker/lock state moves fromcomposeto newtrack. Surface buffersbis written inreflinstead ofdtemporal.sample_partsbecomessample_diffuse/sample_specular/sample_emissionso passes only pull the buffers they need.Rust:
live/targets.rsalways builds one bind group layout per pass; kernel merged buffers expose live-readable ranges at 256-byte alignment for WebGPU offset rules.layout::every_pass_fits_a_browserand runtime checks in merged mode enforce the eight-buffer cap. Docs (ROADMAP,RUNTIME) reflect the new model and measured +0.18 ms cost from thecompose/tracksplit.Reviewed by Cursor Bugbot for commit 14b5f39. Bugbot is set up for automated code reviews on this repo. Configure here.