public sealed class MotionVectorRenderFeatureWhere each object was last frame, and getting that to the velocity pass.
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 NameThe sub-feature's name, for logging and profiling.
public TransformRenderFeature? TransformsWhere the current world matrices come from.
public ShaderStage StagesWhich stages the two matrices are pushed to.
public int OffsetWhere the current matrix goes in the push block.
public int PreviousOffsetAnd where the previous one goes. Sixty-four bytes after it, which is one matrix.
public int RecordCountHow many slots had a matrix last frame, for a test or an inspector.
public ReadOnlySpan<Matrix4x4> PreviousWhat Draw will push as "where this object was".
public bool IsRecording
Methods (2)
protected internal override void Prepare(RenderSystem system)Fills this sub-feature's data for the visible objects.
public void Draw(RenderSystem system, RenderDrawContext context, in RenderNode node)Records this sub-feature's contribution for one node.
Used by (2)
- MotionVectorTestsVixen.Rendering.Tests
- WorldRendererVixen.Engine.Renderer