Modding:Block Tessellator: Difference between revisions

From Vintage Story Wiki
Add table of contents
(Created page with "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 [http...")
 
(Add table of contents)
 
(17 intermediate revisions by the same user not shown)
Line 1: Line 1:
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 [[Modding:Render_Stages|background thread]] when it is marked dirty.
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 [[Modding:Render_Stages|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 [[https://wiki.vintagestory.at/index.php/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 ==
Line 8: Line 10:


The [[Modding:Block_Json_Properties#p_renderpass|renderpass]] property is respected.
The [[Modding:Block_Json_Properties#p_renderpass|renderpass]] property is respected.
The <code>doNotRenderAtLod2</code> property is ignored. The block is always drawn at [[Modding:Level_of_detail|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.
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.
Line 20: Line 24:
== JSON ==
== JSON ==
Draws a json model.
Draws a json model.
=== BlockEntity ===
If the block has a block entity, then [https://apidocs.vintagestory.at/api/Vintagestory.API.Common.BlockEntity.html#Vintagestory_API_Common_BlockEntity_OnTesselation_Vintagestory_API_Client_ITerrainMeshPool_Vintagestory_API_Client_ITesselatorAPI_ OnTesselation] is called on it. OnTesselation may add meshes to the meshpool (meshes to be rendered for the chunk) through the <code>mesher</code> 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 [[Modding:Block_Json_Properties#p_shape|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:
; <code>Lod0Shape</code> (composite shape)
: Shape rendered at close distances
:; <code>FaceCullMode</code> (EnumFaceCullMode&colon; default "default")
:: When set to "collapsematerial" and the <code>Lod0Shape</code> is set, then the <code>Lod0Shape</code> is not rendered when the block is surrounded all sides (except for the bottom, which is ignored).
; <code>Lod2Shape</code> (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.
; <code>DoNotRenderAtLod2</code> (boolean&colon; default false)
: Causes <code>Shape</code> to only be shown at short and medium distances. This only has an effect when <code>Lod2Shape</code> is unset.
The interaction between these properties is rather complicated and the effect of every combination is shown in this table.
<table class="wikitable">
  <tr style="background-color: rgba(0,0,0,0.2);">
    <th style="background-color: rgba(0,0,0,0.2);">Lod0Shape set</th>
    <th style="background-color: rgba(0,0,0,0.2);">Lod2Shape set</th>
    <th style="background-color: rgba(0,0,0,0.2); border-right: 2px solid green;">DoNotRenderAtLod2</th>
    <th style="background-color: rgba(0,0,0,0.2);">Block lighting</th>
    <th style="background-color: rgba(0,0,0,0.2);">Collapsible material and surrounded</th>
    <th style="background-color: rgba(0,0,0,0.2);">Rendered at short distance</th>
    <th style="background-color: rgba(0,0,0,0.2);">Rendered at medium distance</th>
    <th style="background-color: rgba(0,0,0,0.2);">Rendered at far distance</th>
  </tr>
  <tr>
    <td rowspan="6">no</td>
    <td rowspan="4">no</td>
    <td rowspan="2" style="border-right: 2px solid green;">false</td>
    <td>dark</td>
    <td rowspan="6">either</td>
    <td>Shape</td>
    <td style="background-color: rgba(0,0,0,0.2);">none</td>
    <td style="background-color: rgba(0,0,0,0.2);">none</td>
  </tr>
  <tr>
    <td>lit</td>
    <td>Shape</td>
    <td>Shape</td>
    <td>Shape</td>
  </tr>
  <tr>
    <td rowspan="2" style="border-right: 2px solid green;">true</td>
    <td>dark</td>
    <td>Shape</td>
    <td style="background-color: rgba(0,0,0,0.2);">none</td>
    <td style="background-color: rgba(0,0,0,0.2);">none</td>
  </tr>
  <tr>
    <td>lit</td>
    <td>Shape</td>
    <td>Shape</td>
    <td>Shape</td>
  </tr>
  <tr>
    <td rowspan="2">yes</td>
    <td rowspan="2" style="border-right: 2px solid green;">either</td>
    <td>dark</td>
    <td>Shape</td>
    <td style="background-color: rgba(0,0,0,0.2);">none</td>
    <td style="background-color: rgba(0,0,0,0.2);">none</td>
  </tr>
  <tr>
    <td>lit</td>
    <td>Shape</td>
    <td>Shape</td>
    <td>Lod2Shape</td>
  </tr>
  <tr>
    <td rowspan="12">yes</td>
    <td rowspan="8">no</td>
    <td rowspan="4" style="border-right: 2px solid green;">false</td>
    <td rowspan="2">dark</td>
    <td>no</td>
    <td>Lod0Shape and Shape</td>
    <td rowspan="2" style="background-color: rgba(0,0,0,0.2);">none</td>
    <td rowspan="2" style="background-color: rgba(0,0,0,0.2);">none</td>
  </tr>
  <tr>
    <td>yes</td>
    <td>Shape</td>
  </tr>
  <tr>
    <td rowspan="2">lit</td>
    <td>no</td>
    <td>Lod0Shape and Shape</td>
    <td>Shape</td>
    <td>Shape</td>
  </tr>
  </tr>
    <td>yes</td>
    <td>Shape</td>
    <td>Shape</td>
    <td style="background-color: rgba(0,0,0,0.2);">none</td>
  </tr>
  <tr>
    <td rowspan="4" style="border-right: 2px solid green;">true</td>
    <td rowspan="2">dark</td>
    <td>no</td>
    <td>Lod0Shape and Shape</td>
    <td rowspan="2" style="background-color: rgba(0,0,0,0.2);">none</td>
    <td rowspan="4" style="background-color: rgba(0,0,0,0.2);">none</td>
  </tr>
  <tr>
    <td>yes</td>
    <td>Shape</td>
  </tr>
  <tr>
    <td rowspan="2">lit</td>
    <td>no</td>
    <td>Lod0Shape and Shape</td>
    <td rowspan="2">Shape</td>
  </tr>
  <tr>
    <td>yes</td>
    <td>Shape</td>
  </tr>
  <tr>
    <td rowspan="4">yes</td>
    <td rowspan="4" style="border-right: 2px solid green;">either</td>
    <td rowspan="2">dark</td>
    <td>no</td>
    <td>Lod0Shape and Shape</td>
    <td rowspan="2" style="background-color: rgba(0,0,0,0.2);">none</td>
    <td rowspan="2" style="background-color: rgba(0,0,0,0.2);">none</td>
  </tr>
  <tr>
    <td>yes</td>
    <td>Shape</td>
  </tr>
  <tr>
    <td rowspan="2">lit</td>
    <td>no</td>
    <td>Lod0Shape and Shape</td>
    <td rowspan="2">Shape</td>
    <td rowspan="2">Lod2Shape</td>
  </tr>
  <tr>
    <td>yes</td>
    <td>Shape</td>
  </tr>
</table>


== Empty ==
== Empty ==
Line 27: Line 175:
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.
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 [[Modding:Block_Json_Properties#p_renderpass|renderpass]] property is respected. Typically the default "opaque" <code>renderpass</code> is used with the cube tessellator. "transparent" should be used for semitransparent blocks like glass.
The [[Modding:Block_Json_Properties#p_renderpass|renderpass]] property is respected. Typically the default Opaque <code>renderpass</code> is used with the cube tessellator. Transparent should be used for semitransparent blocks like glass.
 
The <code>doNotRenderAtLod2</code> property is ignored. The cube is always drawn at [[Modding:Level_of_detail|level]] 1.


== Cross ==
== Cross ==
Line 33: Line 183:


The [[Modding:Block_Json_Properties#p_renderpass|renderpass]] property is respected.
The [[Modding:Block_Json_Properties#p_renderpass|renderpass]] property is respected.
The <code>doNotRenderAtLod2</code> property is respected. When false, the block is drawn at [[Modding:Level_of_detail|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 ==
== Transparent ==
Line 40: Line 192:
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.
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 <code>renderpass</code> block property is ignored.
The tessellator always uses the Liquid render pass; the <code>renderpass</code> block property is ignored.
 
The <code>doNotRenderAtLod2</code> property is ignored. The block is always drawn at level 1 (visible everywhere within the frustum).


Liquid blocks are recommended to set these properties:
Liquid blocks are recommended to set these properties:
Line 62: Line 216:


The <code>renderpass</code> property only affects the cross. The snow layer is always drawn in the Opaque pass.
The <code>renderpass</code> property only affects the cross. The snow layer is always drawn in the Opaque pass.
The <code>doNotRenderAtLod2</code> property only affects the cross. The snow layer is always drawn at level 1 (visible everywhere within the frustum).


== JSONAndWater ==
== JSONAndWater ==
Line 74: Line 230:
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 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 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 [https://apidocs.vintagestory.at/api/Vintagestory.API.Config.GlobalConstants.html#Vintagestory_API_Config_GlobalConstants_CaveArtColsPerRow 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 [[Modding:Block_Json_Properties#p_renderpass|renderpass]] property is respected.
The [[Modding:Block_Json_Properties#p_renderpass|renderpass]] property is respected.
The <code>doNotRenderAtLod2</code> property is respected. If the block is in the dark, then it is drawn at [[Modding:Level_of_detail|level]] 0 (only visible nearby). Else if <code>doNotRenderAtLod2</code> 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 <code>doNotRenderAtLod2</code> to true.
{{Navbox/modding|Vintage Story}}
Confirmedusers
272

edits