Monday, 13 April 2020

Block Rendering [1.14.4+]

There are a few key points in understanding how block rendering works:
  1. When minecraft is rendering a landscape, it first needs to ‘compile’ the block information (location, appearance, etc) into a list of drawing instructions that the graphics engine can execute.  Typically this means iterating through each block that the player might see and converting each part of the block into a series of textured rectangles.  A simple cube block like stone has six squares, one for each face.  More complicated blocks such as a torch or a piston are made up of a larger number of rectangular faces, perhaps at different angles.  After the render compilation phase is complete, minecraft ends up with a list of rendering instructions (a list of vertices with colour, texture coordinate, and lighting information) that can be executed by the graphics engine to draw the blocks in the landscape.
  2. Most of the blocks in a landscape are static, i.e. they don’t change their shape or position over time.  This allows minecraft to pre-compile a list of rendering instructions for drawing the blocks and then get the graphics engine to execute the list repeatedly, once per frame.  This is much faster than compiling the rendering instructions from scratch every frame.  In general, the drawing instructions only need to be recompiled when blocks in the landscape change.
  3. The blocks in a landscape are rendered in four different ways, depending on their desired appearance (see Picture below).  These are
  • SOLID – fully opaque (i.e. all texels render as opaque, ignoring alpha value).
  • CUTOUT_MIPPED – (alpha testing) - these block textures have holes in them (each texel is either fully opaque or fully transparent) and mip mapping is turned on (mip mapping is a way to improve the appearance of textures – see google for more information).
  • CUTOUT – (alpha testing) – as per CUTOUT_MIPPED except that mip mapping is turned off.
  • TRANSLUCENT – (alpha blending) – these blocks are partially transparent so that you can see other blocks through them – for example ice.  If the fancy graphics option is turned off, these become opaque.  TRANSLUCENT blocks are relatively expensive to render because they have to be pre-sorted in order of their distance from the player, otherwise they won’t render correctly.  TRANSLUCENT blocks can have holes in the texture same as for CUTOUT blocks, i.e. alpha testing is still turned on.

There are four main different "layers" of Block Rendering.  The difference between CUTOUT and CUTOUT_MIPPED is too subtle to show here.

A landscape of blocks is rendered in layers – eg all of the SOLID blocks are drawn first, then the CUTOUT_MIPPED, then the CUTOUT, then the TRANSLUCENT.  A given block will only render in one of the four layers.

Each block also has a render type, specified by BlockRenderType.  This selects the code used to draw the block.
  • MODEL = renders using an IBakedModel.  Each block model is made up of a collection of faces (quads), each of which points in one of the six cardinal directions (i.e. up, down, west, east, north, south).  Vanilla BlockModels are defined in json.  BlockModels are not animated (i.e. their shape does not change) although the texture on each face can be animated (for example like water or lava).
  • INVISIBLE (TESR) = Rendered using a TileEntityRenderer: This is used for blocks which move, change shape, or have an unusual appearance (for example Chest with opening lid, Pistons, Beacons, Signs).
  • ENTITYBLOCK_ANIMATED = inbuilt vanilla renderer

TileEntityRenderers are rendered at a separate time to blocks.  Unlike blocks, which use pre-compiled rendering instructions that are only updated when the landscape changes, TileEntityRenderers do not pre-compile their rendering instructions and are called every frame.

Vanilla classes of interest:

WorldRenderer::updateCameraAndRender
BlockRenderType
BlockModelRenderer

Further information:





1 comment: