Skip to content

PT-6/7/8: skinned meshes in the TLAS, real motion vectors, correctness oracle#94

Merged
proggeramlug merged 3 commits into
mainfrom
feat/pt6-skinned-tlas
Jul 14, 2026
Merged

PT-6/7/8: skinned meshes in the TLAS, real motion vectors, correctness oracle#94
proggeramlug merged 3 commits into
mainfrom
feat/pt6-skinned-tlas

Conversation

@proggeramlug

@proggeramlug proggeramlug commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Summary

Closes the three headline gaps left after the PT roadmap:

  • PT-6 - skinned meshes enter the TLAS. Skinning lived only in the vertex shader, so characters were ghosts to every ray. A compute pre-skin pass now poses each drawn skinned mesh into its PT-megabuffer window (world space - the palette bakes placement, so TLAS instances are identity), per-slot BLASes rebuild each frame from those windows (intersection and hit shading share bytes via first_vertex/first_index), and the instance list extends past the scene nodes. Lumen HW probes see the same instances, so characters contribute to GI too. Also fixes a latent TLAS-capacity bug (recreate when the instance count outgrows the built capacity - wave spawns grow it mid-run).
  • PT-7 - real skinned motion vectors. No previous-frame joint palette existed anywhere; skinned draws wrote exactly zero velocity (TAA/TSR ghosting) and invalidated their own PT history every frame. The palette is now double-buffered (keyed by the FFI anim handle, offsets in lockstep), the scene VS reconstructs last frame''s world position through the EN-022 velocity-reference VP, and the PT kernel reprojects through the velocity MRT when it is non-zero (TAA''s convention), falling back to the camera matrix otherwise.
  • PT-8 - the correctness oracle. Two golden-image tests run the real engine headless on a ray-query device: converged progressive (transport regressions) and realtime-under-camera-motion (reprojection regressions of the prev_vp-transpose class that survived three human review rounds). Skip cleanly without RT hardware. The oracle caught a real bug before it was committed: the kernel RNG was seeded from taa_frame_index, which freezes when TAA is off - progressive accumulation silently never converged (300 frames = 1 frame). PT now keeps its own rolling frame counter.

Verified on the 760M: debug-6 traced view shows the skinned player with interpolated normals (first skinned mesh ever to appear in a traced image); debug-20 history heat shows no rejection hole on animating characters; all 9 golden tests pass; RT gameplay clean at ~19-24 fps.

Docs: docs/pt/PT-6-7-8-skinned-tlas-motion-oracle.md.

https://claude.ai/code/session_018574BdCfSjdpNK3WLgx1hP

Summary by CodeRabbit

  • New Features

    • Added path-tracing support for animated, skinned characters, including dynamic ray-traced shadows and global illumination.
    • Improved motion reprojection for skeletal and character movement, producing smoother temporal results.
    • Added progressive and realtime path-tracing rendering coverage for improved visual correctness.
  • Bug Fixes

    • Prevented animation clips from unexpectedly restarting during transitions.
    • Improved path-tracing history stability and accumulation consistency.

Ralph Kuepper added 3 commits July 14, 2026 21:04
…lections)

Skinned characters were invisible to every ray: skinning happened only
in the vertex shader, so no posed geometry existed for a BLAS and the
TLAS was scene-nodes-only. Now:

- cache_model_if_static retains bind-pose CPU geometry for skinned
  meshes (+ STORAGE usage on their VBs) and their material params.
- draw_model_cached_skinned registers each mesh as a PtDynamicDraw.
- rebuild_instance_data appends a megabuffer window + InstanceGiData
  entry per dynamic draw (white albedo: hit shading multiplies the
  base-colour texture; the geo window gives interpolated normals/UVs).
- A new compute pre-skin pass (PT_SKIN_WGSL, same palette blend as the
  raster VS) overwrites the window position/normal with posed
  WORLD-SPACE data - the joint palette bakes placement, so the TLAS
  instance transform is identity.
- Per-slot BLASes rebuild every frame from the megabuffer windows
  (BLAS reads the same bytes the PT kernel interpolates: first_vertex/
  first_index into the megabuffers, which gain BLAS_INPUT usage).
- The TLAS gains the dynamic instances after the node instances and
  now recreates when the total exceeds the capacity it was built with
  (tlas_created_cap - wave spawns grow the count mid-run).

Lumen HW probe trace sees the same instances, so skinned characters
now contribute to GI as well. Verified: debug-6 traced-primary view
shows the skinned player with interpolated normals (first time any
skinned mesh appears in a traced view); RT gameplay clean at ~24 fps
with waves live.

Claude-Session: https://claude.ai/code/session_018574BdCfSjdpNK3WLgx1hP
…ction

Skinned draws wrote EXACTLY zero velocity: no previous-frame joint
palette existed anywhere and the cached path stamped prev_mvp with the
current VP - enemies ghosted under TAA/TSR and invalidated their own
path-tracer history every frame (young-history blur ring).

- The joint palette is now double-buffered: set_joint_matrices_scaled
  takes a pairing key (the FFI anim handle) and stages last frame''s
  palette for the same model in lockstep, so both arenas share
  offsets. flush uploads both; joint bind group gains binding 1.
- The scene VS reconstructs last frame''s world position from the prev
  palette and projects it through the EN-022 velocity-reference VP -
  skeletal AND locomotion motion now land in the velocity MRT.
- The PT kernel binds the velocity MRT (binding 22): reprojection
  follows per-pixel motion when it is non-zero (TAA''s convention) and
  falls back to the camera prev_vp math otherwise, so moving skinned
  characters keep their SVGF history instead of resetting to 1 spp.

Verified: debug-20 history heat shows no rejection hole on the
animating player; RT gameplay clean.

Claude-Session: https://claude.ai/code/session_018574BdCfSjdpNK3WLgx1hP
…NG seed fix)

Two headless golden tests on a ray-query device (skip cleanly without
one): pt_progressive (converged 300-frame static scene - transport
regressions) and pt_realtime_motion (orbiting camera through the SVGF
history - reprojection regressions of the prev_vp-transpose class that
survived three human review rounds). BLOOM_UPDATE_GOLDEN=1 regenerates.

The oracle caught a real bug before it was committed: the kernel
seeded its RNG from taa_frame_index, which freezes when TAA is off -
the sample sequence froze and progressive accumulation silently never
converged (300 frames rendered the same image as 1). A player turning
TAA off in settings would have hit this in-game. PT now keeps its own
rolling pt_frame_index.

DXC note: on Windows the tests need dxcompiler.dll/dxil.dll loadable
(untracked local copies next to native/shared; gitignored).

Docs: docs/pt/PT-6-7-8-skinned-tlas-motion-oracle.md covers this round.

Claude-Session: https://claude.ai/code/session_018574BdCfSjdpNK3WLgx1hP
@proggeramlug proggeramlug merged commit 66b1964 into main Jul 14, 2026
7 of 10 checks passed
@coderabbitai

coderabbitai Bot commented Jul 14, 2026

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 15433bbe-2f90-4d11-a74f-3e604e2926c8

📥 Commits

Reviewing files that changed from the base of the PR and between eebf2f2 and 6692dae.

⛔ Files ignored due to path filters (2)
  • native/shared/tests/golden/pt_progressive.png is excluded by !**/*.png
  • native/shared/tests/golden/pt_realtime_motion.png is excluded by !**/*.png
📒 Files selected for processing (12)
  • .gitignore
  • docs/pt/PT-6-7-8-skinned-tlas-motion-oracle.md
  • native/shared/src/ffi_core/models.rs
  • native/shared/src/ffi_core/ragdoll_ffi.rs
  • native/shared/src/models.rs
  • native/shared/src/renderer/mod.rs
  • native/shared/src/renderer/model_draw.rs
  • native/shared/src/renderer/pt_pass.rs
  • native/shared/src/renderer/shaders/core.rs
  • native/shared/src/renderer/shaders/mod.rs
  • native/shared/src/renderer/shaders/pt.rs
  • native/shared/tests/golden_render.rs

📝 Walkthrough

Walkthrough

Adds dynamic skinned meshes to path-tracing acceleration structures, tracks previous joint poses for motion vectors, introduces velocity-based PT reprojection, separates PT frame sequencing from TAA, and adds ray-query golden tests.

Changes

Skinned PT pipeline

Layer / File(s) Summary
Previous-pose staging and animation wiring
native/shared/src/ffi_core/models.rs, native/shared/src/ffi_core/ragdoll_ffi.rs, native/shared/src/models.rs, native/shared/src/renderer/mod.rs, native/shared/src/renderer/model_draw.rs
Animation uploads use keyed previous-palette pairing; current and previous joint palettes are staged and uploaded separately, while repeated clip requests remain no-ops during fades.
Dynamic skinned TLAS population
native/shared/src/renderer/mod.rs, native/shared/src/renderer/model_draw.rs, native/shared/src/renderer/shaders/pt.rs, native/shared/src/renderer/shaders/mod.rs
Skinned cached meshes retain bind-pose data, register dynamic draws, run compute pre-skinning, rebuild dynamic BLASes, and append dynamic instances to the TLAS.
Skinned motion vectors and PT reprojection
native/shared/src/renderer/shaders/core.rs, native/shared/src/renderer/shaders/pt.rs, native/shared/src/renderer/pt_pass.rs, native/shared/src/renderer/mod.rs, native/shared/src/renderer/model_draw.rs
Previous skinned positions generate velocity MRT data; PT reprojection uses raster velocity with prev_vp fallback, and PT sampling advances with pt_frame_index.
Ray-query oracle and supporting documentation
native/shared/tests/golden_render.rs, .gitignore, docs/pt/PT-6-7-8-skinned-tlas-motion-oracle.md
Adds progressive and realtime-motion ray-query goldens, skips unsupported environments, ignores DXC runtime DLLs, and documents the pipeline and validation workflow.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant SkinnedDraw
  participant Renderer
  participant PreSkin
  participant TLAS
  participant PT
  SkinnedDraw->>Renderer: register dynamic skinned draw
  Renderer->>PreSkin: write posed vertices to PT megabuffer
  PreSkin->>TLAS: provide updated BLAS geometry
  TLAS->>PT: expose skinned instances for ray queries
  Renderer->>PT: bind raster velocity and advance PT frame index
  PT->>PT: reproject using velocity or prev_vp
Loading

Possibly related PRs

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/pt6-skinned-tlas

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

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