Vixen
02b45cc4
csharp
public sealed class MeshRenderer

Draws world-space triangles: a block-out primitive, a debug hull, a preview.

Read the guide page for this →

Remarks

LineRenderer for surfaces, and deliberately its twin. Same ring of host-visible buffers, same one draw call a frame, same absence of a model matrix and of anything per-object. What a caller hands over is triangles that are already where they go, so a scene of twenty primitives is one buffer write rather than twenty draws with twenty descriptor sets behind them.

⚠ This is not the mesh path. The renderer proper is RenderSystem and its features: culling, sorting, instancing, materials, a pipeline per effect permutation. That is what a game draws its world with, and this would be a bad substitute for it — the vertices go through the CPU every frame, so the cost is linear in vertices rather than in objects. What it is good for is what a debug line list is good for: geometry that belongs to a tool rather than to a scene, where being able to draw anything at all with no material system attached is worth more than throughput.

⚠ And a scene's shapes are not that, which is what MeshInstanceRenderer is for. The distinction is whether the geometry changes: a gizmo handle is a different size and colour at every camera position and there is one of it, so rebuilding it per frame is the cheap answer. A block-out mesh is the same geometry for as long as nobody edits it, and there are thousands, so paying per vertex per frame for it is the thing docs/plan/24-blockout-tools.md § B1 called a blocker.

⚠ Indexed, unlike the line renderer, and it has to be. A sphere's vertices are shared by six triangles each; expanding them would sextuple the bytes that cross the bus every frame for geometry that has not moved. The index buffer is a second ring, written in the same call, and a caller appending a second mesh has to offset its indices — which Upload does not do for them, because a caller building a frame's geometry knows where each mesh started and this does not.

⚠ Two-sided, and lit as though it were not. Which winding is front depends on the projection, the viewport's Y direction and the handedness of whatever produced the geometry, and a tool renderer that draws nothing at all when one of the three disagrees is a bad way to find that out. The fragment stage flips the normal for a back face instead, so the inside of an open shape is lit rather than black.

Fields and properties (9)

  • public int VertexCapacity

    How many vertices fit in one frame's region.

  • public int IndexCapacity

    How many indices fit in one frame's region.

  • public int Regions

    How many regions the ring has.

  • public int Region

    Which region the last upload wrote.

  • public int Count

    How many indices the last upload held.

  • public int Draws

    How many draws the last record issued.

  • public int Dropped

    How much of the last upload was dropped for want of room, in indices.

  • public Vector3 LightDirection

    Which way the light comes from, in world space.

  • public float Ambient

    How much light a surface facing away still receives, from zero to one.

Methods (4)

  • public MeshRenderer(IGraphicsDevice device, MeshShaders shaders, RenderOutput output, int vertexCapacity = 65536, int indexCapacity = 262144)

    Builds the pipeline a frame's triangles are drawn with.

  • public void Upload(ReadOnlySpan<MeshVertex> mesh, ReadOnlySpan<uint> triangles)

    Writes a frame's triangles into the next region of the ring.

  • public void Record(ICommandList commands, in Matrix4x4 viewProjection, bool depthTested = true)

    Draws what the last upload wrote.

  • public void Dispose()

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

Used by (1)

  • ScenePresenterVixen.Editor.App