Vixen
02b45cc4
csharp
public sealed class MotionVectorRenderFeature

Where each object was last frame, and getting that to the velocity pass.

Read the guide page for this →

Remarks

The half of a motion vector that a view cannot supply. PreviousViewProjection catches a camera that moved; this catches an object that moved while the camera did not. A pass with only the first is the depth-reprojection trick, which is correct for static geometry and wrong for everything motion vectors exist for.

Its own sub-feature rather than two more fields on TransformRenderFeature, and the reason is that feature's records path. With UseRecords on — which is every device with HasDrawIndirectCount — that feature pushes nothing at all, because a push is per draw and a merged command has no point inside it at which to push the second object's matrix. The velocity pass is not a merged pass and does need its matrices pushed, so it gets a contributor that always pushes and a shader that always reads a push constant.

⚠ Both matrices, not just the previous one. When records are on nothing else pushes world either, so this pass would draw every object at whatever record zero holds. Pushing both is also what keeps the shader's contract one thing: MotionVectors.rvn declares a 128-byte range covering exactly these two, which is Vulkan's guaranteed push size and therefore the budget.

⚠ It contributes nothing to any other pass, and that is checked by offset rather than by name. ForwardPlus declares a 64-byte range, so offset 64 falls outside it and this pushes nothing there — a push into a range a layout does not have is a validation error on every draw, not a value quietly dropped.

How the history is kept. Two arrays and a swap per frame. Extraction writes this frame's world matrices before Prepare runs, so Prepare moves what it recorded last frame into the array Draw reads and then records this frame's into the other. A slot with no history — an object drawn for the first time, or one whose slot was recycled — takes its current matrix, which reports no motion. Leaving the zero matrix there instead would project the object to the origin and hand the whole silhouette a vector pointing at the middle of the screen.

Fields and properties (8)

  • public override string Name

    The sub-feature's name, for logging and profiling.

  • public TransformRenderFeature? Transforms

    Where the current world matrices come from.

  • public ShaderStage Stages

    Which stages the two matrices are pushed to.

  • public int Offset

    Where the current matrix goes in the push block.

  • public int PreviousOffset

    And where the previous one goes. Sixty-four bytes after it, which is one matrix.

  • public int RecordCount

    How many slots had a matrix last frame, for a test or an inspector.

  • public ReadOnlySpan<Matrix4x4> Previous

    What Draw will push as "where this object was".

  • public bool IsRecording

Methods (2)

Used by (2)

  • MotionVectorTestsVixen.Rendering.Tests
  • WorldRendererVixen.Engine.Renderer