Vixen
02b45cc4
csharp
public sealed class TransformRenderFeature

Where each object is, and getting that to the shader.

No guide page documents this yet — the page shows what the code says about itself.

Remarks

A sub-feature rather than a field on RenderObject, and it is the clearest case for why: a UI quad in screen space and a particle billboard built in the vertex shader both have bounds and both need culling, and neither has a world matrix. Putting one on every object would make them carry sixty-four bytes to say nothing.

Two ways to the shader, and which one is a decision about the frame. By default the matrix is a push constant: the smallest and most per-draw thing a frame has, travelling in the command buffer with no descriptor, no allocation from an upload ring and no offset to track. A mat4 is 64 bytes against Vulkan's guaranteed 128, so it fits everywhere with room to spare — and Raven warns at RVN3007 if a shader's block exceeds that, so the two sides agree about the budget.

But a pushed constant is per draw, and that is what stops draws merging. A merged command covers several objects, and there is no point inside one at which a host could push the second object's matrix. EnableRecords is the other way: every object's matrix goes into one buffer at its own slot, and the draw carries the slot in its own firstInstance — which the API adds into gl_InstanceIndex before the vertex stage runs, and which the compaction shader copies along with the rest of the command. Not a new mechanism: it is the one InstancingRenderFeature already uses, with a run of one.

The matrix is sent as-is either way: the engine stores row-major with the translation in M41..M43, the shader reads the same bytes as ColMajor, and that makes its matrix the transpose mul(v, M) wants. Transposing here would compute the wrong transform more expensively — see docs/plan/07 § E.

Fields and properties (14)

  • public override string Name

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

  • public RenderDataKey<Matrix4x4> World

    Each object's object-to-world matrix.

  • public ShaderStage Stages

    Which stages the transform is pushed to. Vertex only, by default.

  • public int Offset

    Where in the push-constant block the transform goes.

  • public IGraphicsDevice? Device

    The device the record buffer lives on. Set before EnableRecords.

  • public bool UseRecords

    Whether this frame's matrices go into a buffer rather than into each draw's push constants.

  • public BufferHandle Buffer

    The buffer every record lives in, for a host binding it once a frame.

  • public int BaseIndex

    Which record this frame's first object is, so a shader can add it to the instance index.

  • public int RecordCount

    How many records this frame holds.

  • public ReadOnlySpan<Matrix4x4> Records

    What was written this frame, for a test or an inspector.

  • public ParameterCollection? Scene

    Where to publish the record buffer and its base, or null to publish them nowhere.

  • public string ShaderName

    Which pass's names to publish under.

  • public IReadOnlyList<PermutationKey<bool>> PermutationKeys

    The permutation keys this sub-feature decides.

  • public bool IsRecording

Methods (7)

  • public bool ValueOf(RenderSystem system, RenderObjectId id, int index)
  • protected internal override void Initialize(RenderSystem system)

    Registers this sub-feature's per-object data. Called once.

  • public bool EnableRecords(PermutationKey<bool> shaderKey)

    Turns the record path on where a merged draw is possible, and leaves it off where it is not.

  • protected internal override void Prepare(RenderSystem system)
  • public void Draw(RenderSystem system, RenderDrawContext context, in RenderNode node)

    Records this sub-feature's contribution for one node.

  • public int RecordIndexOf(RenderSystem system, RenderObjectId id)
  • public void Dispose()

    Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.

Used by (27)

  • ArenaThirdPersonShooter
  • BindlessFrameTestsVixen.Rendering.Tests
  • ClusteredShadingDeviceTestsVixen.Graphics.Golden.Tests
  • CompositorBuilderVixen.Rendering
  • CompositorImageTestsVixen.Graphics.Golden.Tests
  • DrawCompactionTestsVixen.Rendering.Tests
  • ForwardFrameTestsVixen.Rendering.Tests
  • GpuDrivenCompositorTestsVixen.Rendering.Tests
  • HarnessVixen.Rendering.Tests
  • HarnessVixen.Rendering.Tests
  • HarnessVixen.Rendering.Tests
  • HarnessVixen.Rendering.Tests
  • IrradianceBounceDeviceTestsVixen.Graphics.Golden.Tests
  • IrradianceShadingDeviceTestsVixen.Graphics.Golden.Tests
  • MaterialBindingTestsVixen.Rendering.Tests
  • MaterialRecordBufferTestsVixen.Rendering.Tests
  • MaterialTextureIndexTestsVixen.Rendering.Tests
  • MeshExtractionSystemVixen.Rendering
  • MeshExtractionTestsVixen.Rendering.Tests
  • MeshRenderFeatureTestsVixen.Rendering.Tests
  • MotionVectorRenderFeatureVixen.Rendering
  • MotionVectorTestsVixen.Rendering.Tests
  • SkinningAndInstancingTestsVixen.Rendering.Tests
  • TransformRecordTestsVixen.Rendering.Tests
  • VirtualGeometryExtractionTestsVixen.Rendering.Tests
  • VirtualGeometryGoldenTestsVixen.Graphics.Golden.Tests
  • WorldRendererVixen.Engine.Renderer