vat: website demo tabs + MultiMesh perf comparison + web build fixes - #644
Conversation
Builds on PR #640 (which landed the bake/harness pipeline). This patch wires the demo into the marketing site as three browser-runnable tabs: - "Showcase" single VAT dancer + orbit camera - "1000× VAT" MultiMeshInstance3D + INSTANCE_CUSTOM frame phase - "1000× skeletal" 1000 SkinnedMeshRenderer clones (cached PackedScene) Notable fixes: - Web export couldn't find the dancer (raw .gltf/.png aren't bundled in the Godot .pck — only imported .scn/.ctex). VATInstance.gd and both perf spawners now go through `load("res://...")` so resources resolve in the web sandbox. - VAT perf demo was slower than skeletal because every instance had its own ShaderMaterial. Switched to a single MultiMesh + per- instance phase via INSTANCE_CUSTOM — one draw call per surface instead of N. - Vsync now off at project level (`window/vsync/vsync_mode=0`) — on macOS Metal the runtime DisplayServer call alone is too late. - Single Godot web export with URL-based scene routing (`?scene=web|perf_vat|perf_skeleton`) via a Bootstrap.gd entry — avoids 3× the 36 MB WASM in `website/public/demo/`. Frontend: - New <VATDemo> React component with tab switcher (a11y roles + keyboard nav) and per-tab captions explaining what the visitor is looking at. - Drops the old static screenshot block from App.jsx / App.module.css.
|
Warning Rate limit exceeded
You’ve run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (12)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 925050c619
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| <div className={styles.tabs} role="tablist" aria-label="VAT demo selector"> | ||
| {TABS.map((t) => ( | ||
| <button | ||
| key={t.id} | ||
| type="button" | ||
| role="tab" | ||
| aria-selected={tab.id === t.id} |
There was a problem hiding this comment.
Implement real ARIA tab behavior for demo tabs
This introduces role="tablist"/role="tab" semantics without the expected tab pattern wiring (aria-controls/tabpanel relationship and keyboard interaction such as arrow-key navigation with roving focus), so assistive tech users get a widget that is announced as tabs but does not behave like one. In practice this makes keyboard and screen-reader navigation inconsistent and can block users from understanding which panel is controlled by each tab.
Useful? React with 👍 / 👎.
Codex flagged that the tablist/tab semantics on <VATDemo> weren't
backed by the rest of the ARIA tab pattern. Added:
- aria-controls + aria-labelledby wiring between each tab button
and its panel, with stable id="vat-tab-<id>" / "vat-panel-<id>"
- role="tabpanel" on the iframe wrapper
- Roving tabIndex (the active tab is the only one in the tab
order; others are -1)
- Arrow-key navigation: Left/Right cycle, Home/End jump to
ends — focus follows selection, matching the WAI-ARIA "tabs
with automatic activation" pattern
|
Bumps the project version to 3.3.0 in CMakeLists.txt (single source of truth — sync-doc-versions-from-cmake.sh propagates to README and the website's pinned action ref). The 3.x.y → 3.3.0 minor bump reflects the VAT pipeline (PRs #640 / #644 / #646 / #647 landing together): - `qtmesh vat <file> --anim <name> -o <dir>` CLI subcommand - OpenVAT-format 16-bit position+normal bake - Vertex-order-aligned source.gltf + Ogre bind sidecar so engine importers can realign UV2 to the bake's column order - Drop-in shader templates for Godot/Unity/Unreal at tools/vat-shaders/ - Live website demo at /#vat-demo (Showcase + 1000× VAT vs 1000× skeletal perf comparison) Website updates: - Deep-linking to any section (e.g. `/#vat-demo`, `/#install`, `/#cli`) now works on both initial load (React-mount-aware scroll-into-view via requestAnimationFrame) and during in-session hashchanges (smooth scroll). - Each Section title gains a hover-visible `#` anchor link so visitors can grab a shareable URL without dev-tools. - New "VAT" tab on the home page's CLI examples panel with a full `qtmesh vat` command demo. - New `cmd-vat` reference section in the docs (synopsis, options, examples, sidebar entry). - `scroll-behavior: smooth` + `scroll-margin-top: 1.5rem` on `section[id]` so anchor-scroll lands with breathing room rather than flush against the viewport top edge.



Summary
Builds on PR #640 (which landed the OpenVAT bake pipeline + Godot harness).
This patch wires the demo into the marketing site as three browser-runnable
tabs so visitors can compare the techniques side-by-side without leaving
the homepage.
demo_web.tscndemo_perf_vat.tscnMultiMeshInstance3D+INSTANCE_CUSTOMper-instance frame phasedemo_perf_skeleton.tscnSkinnedMeshRendererclones — the "best practice" baselineLocal numbers (M2 Max, ProMotion 120 Hz, vsync OFF):
Notable fixes shipped here
.gltf/.pngaren'tbundled in Godot's
.pck— only the imported.scn/.ctex.VATInstance.gdand both perf spawners now go throughload("res://...")so resources resolve inside the web sandbox.
its own
ShaderMaterial. Switched to one sharedMultiMesh+ per-instance phase via
INSTANCE_CUSTOM.r— one draw call per surfaceinstead of N.
window/vsync/vsync_mode=0). OnmacOS Metal the runtime
DisplayServer.window_set_vsync_modecallalone is too late: Metal binds vsync at window creation, before any
GDScript runs.
?scene=web|perf_vat|perf_skeleton)via a tiny
Bootstrap.gdentry — avoids shipping 3× the 36 MB WASMin
website/public/demo/.Frontend
<VATDemo>React component with tab switcher (properrole="tablist"looking at.
App.jsx/App.module.css.Test plan
cd website && npm run buildproduces a clean static bundle withpublic/demo/copied throughindex.html?scene=weband animates the Rumba dancerperf_vat→ grid of 1000 dancers, FPS overlay shows headroom > display refreshperf_skeleton→ identical grid, FPS overlay shows the skinned baseline🤖 Generated with Claude Code