Modding:Block Tessellator: Difference between revisions

From Vintage Story Wiki
(→‎JSON: Describe level of detail handling)
(Add table of contents)
 
Line 2: Line 2:


The chunk tessellator calls a block tessellator for each block in the chunk. Blocks select their tessellator through the [[Modding:Block_Json_Properties|drawtype]] property. The property value is an [https://apidocs.vintagestory.at/api/Vintagestory.API.Client.EnumDrawType.html EnumDrawType], and the parsing is case insensitive.
The chunk tessellator calls a block tessellator for each block in the chunk. Blocks select their tessellator through the [[Modding:Block_Json_Properties|drawtype]] property. The property value is an [https://apidocs.vintagestory.at/api/Vintagestory.API.Client.EnumDrawType.html EnumDrawType], and the parsing is case insensitive.
__TOC__


== BlockLayer ==
== BlockLayer ==

Latest revision as of 06:43, 30 October 2023

Each visible chunk is tessellated into a mesh, and that mesh is reused until the chunk is unloaded, or the chunk is marked dirty. The chunk is retessellated on a background thread when it is marked dirty.

The chunk tessellator calls a block tessellator for each block in the chunk. Blocks select their tessellator through the drawtype property. The property value is an EnumDrawType, and the parsing is case insensitive.

BlockLayer

The BlockLayer tessellators draw a cube with the top cut off. In vanilla it is only used by the charcoal pile block. The block properties should specify a texture for all 6 sides of the block, or specify the same texture for all sides through the "all" alias. The texture is anchored at the top of the block.

The renderpass property is respected.

The doNotRenderAtLod2 property is ignored. The block is always drawn at level 1.

Specifically, this tessellator category contains 7 tessellators. The number at the end represents how tall to draw the block, in eighths of a block. BlockLayer_0 is not a valid tessellator, because the surface tessellator is more appropriate for a 0 high block. BlockLayer_8 is not a valid tessellator, because Cube should be used instead for full blocks.

  • BlockLayer_1
  • BlockLayer_2
  • BlockLayer_3
  • BlockLayer_4
  • BlockLayer_5
  • BlockLayer_6
  • BlockLayer_7

JSON

Draws a json model.

BlockEntity

If the block has a block entity, then OnTesselation is called on it. OnTesselation may add meshes to the meshpool (meshes to be rendered for the chunk) through the mesher parameter. It may return false, in which case the json mesh file is still processed. Or it may return true to skip processing the json mesh file.

Level of detail

Most blocks only use the Shape property and leave the other render settings at the default. This causes the shape to be rendered as long as it is visible within the frustum. However, there are some properties to adjust the level of detail at different render distances:

Lod0Shape (composite shape)
Shape rendered at close distances
FaceCullMode (EnumFaceCullMode: default "default")
When set to "collapsematerial" and the Lod0Shape is set, then the Lod0Shape is not rendered when the block is surrounded all sides (except for the bottom, which is ignored).
Lod2Shape (composite shape)
When set, this is rendered at far distances. The rendering of the regular shape is changed such that it is only shown at short and medium distances.
DoNotRenderAtLod2 (boolean: default false)
Causes Shape to only be shown at short and medium distances. This only has an effect when Lod2Shape is unset.

The interaction between these properties is rather complicated and the effect of every combination is shown in this table.

Lod0Shape set Lod2Shape set DoNotRenderAtLod2 Block lighting Collapsible material and surrounded Rendered at short distance Rendered at medium distance Rendered at far distance
no no false dark either Shape none none
lit Shape Shape Shape
true dark Shape none none
lit Shape Shape Shape
yes either dark Shape none none
lit Shape Shape Lod2Shape
yes no false dark no Lod0Shape and Shape none none
yes Shape
lit no Lod0Shape and Shape Shape Shape
yes Shape Shape none
true dark no Lod0Shape and Shape none none
yes Shape
lit no Lod0Shape and Shape Shape
yes Shape
yes either dark no Lod0Shape and Shape none none
yes Shape
lit no Lod0Shape and Shape Shape Lod2Shape
yes Shape

Empty

Skips tessellating the block.

Cube

Draws a full height cube. The block properties should specify a texture for all 6 sides of the block, or specify the same texture for all sides through the "all" alias.

The renderpass property is respected. Typically the default Opaque renderpass is used with the cube tessellator. Transparent should be used for semitransparent blocks like glass.

The doNotRenderAtLod2 property is ignored. The cube is always drawn at level 1.

Cross

The CrossTesselator is used by tallgrass (and other heights). It only uses the "north" and "south" textures of the block. It draws the two rectangles from one corner the other such that they intersect at a line going from the center of the bottom face to the center of the top face. If the randomizeRotations property of the block is true, then the tesselator rotates the cross about the y axis.

The renderpass property is respected.

The doNotRenderAtLod2 property is respected. When false, the block is drawn at level 1 (always visible). When true, the block is drawn at level 2 (not visible far away). This was previously used to stop far away grass from rendering (set doNotRenderAtLod2 to true), but that property was removed from the tallgrass block in 1.17.0-pre.1.

Transparent

This tessellator appears to be deprecated. Instead use the cube tessellator with the renderpass property set to "transparent".

Liquid

Renders the block as a cube with the top chopped off, based on the Modding:Block_Json_Properties#p_liquidlevel liquidLevel block property. The tessellator also looks at the neighboring blocks to see if the liquid is flowing towards them, and if so it adjusts the angle of the top of the cube. It also adds custom ints and floats to the mesh to handle rendering waves in the liquid.

The tessellator always uses the Liquid render pass; the renderpass block property is ignored.

The doNotRenderAtLod2 property is ignored. The block is always drawn at level 1 (visible everywhere within the frustum).

Liquid blocks are recommended to set these properties:

sideopaque: { all: false },
drawtype: "liquid",
renderpass: "liquid",
matterstate: "liquid"

TopSoil

CrossAndSnowlayer

This draws a cross just like the cross tessellator, but it also draws a snow layer at the bottom of the cube. These are the exact tessellators in this category:

  • CrossAndSnowlayer - 1/8th block of snow
  • CrossAndSnowlayer_2 - 2/8th block of snow
  • CrossAndSnowlayer_3 - 3/8th block of snow
  • CrossAndSnowlayer_4 - 4/8th block of snow

The snow layer uses the top texture of the snowlayer-1 block.

The renderpass property only affects the cross. The snow layer is always drawn in the Opaque pass.

The doNotRenderAtLod2 property only affects the cross. The snow layer is always drawn at level 1 (visible everywhere within the frustum).

JSONAndWater

JSONAndSnowLayer

SurfaceLayer

This draws decors on the surface of parent blocks. This only works for decor blocks.

Only the culled faces are drawn, which is the opposite of most tessellators that draw everything except the culled faces. Typically the culled faces are those should not be drawn because they would not be seen anyway. The chunk renderer has special logic for decor blocks. It only marks only the face touching the parent block to be culled. That is correct for decor blocks with non-zero thickness, because the face touching the parent block is not visible. However, for decor blocks with 0 thickness, either the front or back face (normally culled) should be drawn, but not both. So the surface tessellator draws the culled face, because it is easier to find than the front face. This is also why the tessellator does not work for non-decor blocks.

The texture is selected from the decor block based on which side of the parent block it is rendered on. So blocks using the renderer should include a texture for all 6 sides, typically through the "all" name.

The decor subposition handling is hardcoded to only work with caveart type blocks. If the decor has a subposition, the tessellator selects a glyph from the texture. The GlobalConstants.CaveArtColsPerRow constant is used for both the glyphs per row and glyphs per column. If the decor extends past the end of the block, the extension is rendered if the neighboring block has the same material, otherwise the glyph is cropped at the end of the block so that the glyph isn't showing hanging off the end of the block.

The renderpass property is respected.

The doNotRenderAtLod2 property is respected. If the block is in the dark, then it is drawn at level 0 (only visible nearby). Else if doNotRenderAtLod2 is true, then it is drawn at level 2 (visible up to medium distances). Else, it is drawn at level 1 (visible everywhere within the frustum). Most decors set doNotRenderAtLod2 to true.

Icon Sign.png

Wondering where some links have gone?
The modding navbox is going through some changes! Check out Navigation Box Updates for more info and help finding specific pages.

Modding
Modding Introduction Getting Started Theme Pack
Content Modding Content Mods Developing a Content Mod Basic Tutorials Intermediate Tutorials Advanced Tutorials Content Mod Concepts
Code Modding Code Mods Setting up your Development Environment
Property Overview ItemEntityEntity BehaviorsBlockBlock BehaviorsBlock ClassesBlock EntitiesBlock Entity BehaviorsCollectible BehaviorsWorld properties
Workflows & Infrastructure Modding Efficiency TipsMod-engine compatibilityMod ExtensibilityVS Engine
Additional Resources Community Resources Modding API Updates Programming Languages List of server commandsList of client commandsClient startup parametersServer startup parameters
Example ModsAPI DocsGitHub Repository