Skip to content

merging in PR #52 - #57

Merged
iwald-nvidia merged 5 commits into
NVIDIA:mainfrom
ingowald:main
Sep 11, 2026
Merged

iwald-nvidia merged 5 commits into
NVIDIA:mainfrom
ingowald:main

Conversation

@ingowald

Copy link
Copy Markdown
Contributor

This merges in @mvictoras PR #52 , with all conflicts resolved via this MR

mvictoras and others added 5 commits July 13, 2026 15:02
Adds screen-space motion vectors (per-pixel Δpixels between the current
and previous frame's projected position of the same world point). This
is the essential input for temporal upsamplers like DLSS, FSR2, and
XeSS. Without it, applications must approximate motion vectors from a
full-screen camera-only depth reprojection, which cannot represent
per-object motion and causes visible ghosting on moving geometry.

New public API:
  * BN_FB_MOTION channel enum (vec2f per pixel, screen-space pixel delta)
  * bnSetInstanceMotionDeltas(model, slot, BNTransform*, n) - per-instance
    motion delta transform, defined as prev * inverse(curr). Optional;
    when unset, only camera motion contributes.
  * ANARI parameters on Camera: motion.viewProjection and
    motion.previousViewProjection (both ANARI_FLOAT32_MAT4). Both must
    be supplied for the motion channel to be written.
  * ANARI parameter on Instance: motion.transform (ANARI_FLOAT32_MAT4,
    the instance's transform on the previous frame). Optional per
    instance; defaults to the current transform.
  * ANARI framebuffer channel: channel.motion (ANARI_FLOAT32_VEC2).

Design choices:
  * Delta form (prev * inv(curr)) rather than raw prev transform,
    computed on the ANARI shim side. Barney has no device-side
    per-instance current-transform array (transforms live inside the
    RTC/OptiX BVH), so shading with raw prev transforms would require
    inverting the current transform per pixel in the hot ray shader
    path. Delta form is one CPU inverse per instance per frame in
    exchange for zero inverses in the kernel.
  * Screen-space pixels rather than world-space velocity: matches
    DLSS/FSR2/XeSS conventions and DirectX/Vulkan raster MV output.
    Zero downstream reprojection needed.
  * BN_FB_MOTION added to FrameBuffer::needHitIDs() mask - the shade
    kernel reads hitIDs[tid].instID to look up per-instance motion
    deltas, and without this the hitIDs buffer is never populated for
    motion-only channel requests.

Shading:
  In shadeRays.cu, at the accumID==0 && generation==0 aux-write block:
    world_hit  = ray.P
    prev_world = motionDeltas[instID] * world_hit  (if deltas supplied)
    delta_ndc  = 0.5 * (project(curr_vp, world_hit) -
                        project(prev_vp, prev_world))
    motion     = delta_ndc * fbSize  (in pixels)
  Guarded by camera.haveMotionMatrices - falls back to no-op if the app
  did not supply the motion.viewProjection matrices.

Framebuffer plumbing:
  * MotionChannelTile (vec2f per pixel) parallel to AuxChannelTile
  * TiledFB: alloc + linearize kernel (linearizeMotionTiles)
  * FrameBuffer: linearMotionChannel staging + gatherMotionChannel +
    writeMotionChannel virtuals; MPI-gather runs in finalizeFrame() so
    send/recv pair correctly across all ranks
  * DistFB: MPI send/recv path templated on MotionChannelTile
  * LocalFB: single-node overrides

resetAccumulation() extended to zero the motion tiles on every device
at the start of each frame - the shade kernel writes only on hits, so
unwritten pixels (background) would otherwise retain stale motion
values from previous frames, causing 'ghost silhouette' artifacts.

Backward compatibility: all changes are additive. Existing apps that
don't request BN_FB_MOTION are unaffected. Existing sample apps
verified to produce identical output.

Testing: full end-to-end verified on three ANARI examples with correct
motion vectors driving NVIDIA DLSS temporal upscaling. Motion vector
corruption tests (zero / negate / exaggerate / noise) confirm DLSS
consumes the channel and its output measurably degrades on corruption.
@iwald-nvidia
iwald-nvidia merged commit 2d57d0c into NVIDIA:main Sep 11, 2026
14 checks passed
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.

3 participants