Modding:Render Stages

From Vintage Story Wiki

Renderers can be added with api.Event.RegisterRenderer. The renderState parameter describes which stage to insert the new renderer in. Within that stage, the renderers are ordered based on their RenderOrder fields. Note that the documentation for RenderOrder lists the standard renderers in a slightly wrong order. The shadow stages are actually run between the before and opaque stages.

The collection of blocks placed in the world is called the terrain. The process of converting the terrain into meshes for rendering is called tessellation. The terrain is divided into chunks. Each chunk is tessellated as a whole, by calling the block tessellator for each block in the chunk. If any block in the chunk is marked as dirty, then the entire chunk is marked as dirty, and all of the blocks in the chunk are retessellated.

Rendering runs on the main thread, but for performance reasons the terrain tessellation runs on the tesselateterrain thread. The tessellation thread pulls chunks out of a request queue, tessellates them, and puts the result in a completion queue. The main thread pulls tessellated chunks from the completion queue and updates the tessellated chunk meshes in the MeshDataPoolManagers.

The terrain tessellation is stored in MeshDataPoolManagers, which is a jagged array. The outer array has an entry for EnumChunkRenderPass. The inner array contains an entry for every block texture atlas. A MeshDataPoolManager is responsible for copying the new chunk mesh into the graphics card, and removing the chunk's old mesh. All of the meshes in a MeshDataPoolManager use textures from the same texture atlas.

Each mesh in the MeshDataPoolManager is tracked with a ModelDataPoolLocation. Each location stores a bounding sphere of the mesh and the mesh's level of detail. On every frame, the MeshDataPoolManagers iterate through all of their mesh locations and to decide whether to draw or cull it, based on the distance from the camera and the mesh's level of detail.

Chunk render passes

The chunk render pass defines the order in which the tessellated terrain chunks are rendered. Below is the rough order of the passes, but keep in mind that many of the chunk render passes are actually run in multiple render stages on each frame. The render stages section shows which render passes are run in multiple stages.

Opaque
Used for solid blocks with no half transparency.
TopSoil
Used for grass covered blocks. Allows for a smooth transition from grass to soil, while still allowing climate tinting of grass.
BlendNoCull
OpaqueNoCull
Used for non-solid single faced blocks, such as tall grass.
Liquid
Used for liquids, produces waves.
Transparent
Use for solid halftransparent blocks, such as glass
Meta
Only if show meta blocks is enabled (hit F4 in creative mode)

Render stages

The API documentation for EnumRenderStage has a brief description of what each render stage does, but it lists them in the wrong order. Below is actual the order of the render stages. The sublists explain the major renders in the stages.

Before
0.99
Pulls chunks out of the tessellation completion queues and updates them in the chunk renderer's MeshDataPoolManagers.
ShadowFar
Only executed if the shadow quality is set high enough in the graphics settings.
0.37 - system terrain shadow far pass
Opaque chunk render pass
TopSoil chunk render pass
BlendNoCull chunk render pass
OpaqueNoCull chunk render pass
ShadowFarDone
Only executed if ShadowFar was executed.
ShadowNear
Only executed if the shadow quality is set high enough in the graphics settings.
0.37 - system terrain shadow near pass
Opaque chunk render pass
TopSoil chunk render pass
BlendNoCull chunk render pass
OpaqueNoCull chunk render pass
ShadowNearDone
Only executed if ShadowNear was executed.
Opaque
0.37 - system terrain opaque pass
Opaque chunk render pass
TopSoil chunk render pass
BlendNoCull chunk render pass
OpaqueNoCull chunk render pass
OIT
Only executed if TransparentRenderPass is enabled in the graphics settings.
0.37 - system terrain OIT pass
Liquid chunk render pass
Transparent chunk render pass
Meta chunk render pass
Only if show meta blocks is enabled (hit F4 in creative mode)
AfterOIT
AfterPostProcessing
AfterFinalComposition
AfterBlit
Ortho
Done

Debugging

The .debug renderers print command lists the class type of every registered renderer, but it does not show which render stages they are registered in, or the order of the renderers.