ChunkMesh changes

4D enthusiast

New Member
The way different block rendering types is handled is currently quite messy, and I think it could be improved reasonably easily, but I wanted to get some feedback first (and also wait until some other PRs are finished before actually starting on this). I assume @manu3d, @Immortius and @vampcat may be interested, I don't know who else.

To summarise how it currently works, as far as I understand:
As each block mesh is generated, it's added to one of 4 meshes for its chunk, one for each RenderType (OPAQUE, TRANSLUCENT, BILLBOARD and WATER_AND_ICE). By default, if a block has the doubleSided flag (which also controls how it waves around, if it's animated), it's BILLBOARD. Otherwise, it it has the water or ice flags, it's WATER_AND_ICE, and if none of the above, it's either TRANSLUCENT or OPAQUE depending on whether it has the translucent flag.
Each chunk rendering node passes a ChunkMesh.RenderPhase to the ChunkMesh, to retrieve the appropriate mesh for that phase. this has values OPAQUE (renders RenderType.OPAQUE), ALPHA_REJECT (renders RenderType.TRANSLUCENT and RenderType.BILLBOARD), REFRACTIVE (renders RenderType.WATER_AND_ICE) and Z_PRE_PASS (which seems to be unused). OPAQUE is used by OpaqueBlocksNode, ShadowMapNode and WorldReflectionNode, ALPHA_REJECT is used by AlphaRejectBlocksNode, and REFRACTIVE is used by RefractiveReflectiveBlocksNode

There are several things that don't make sense to me about this:
  • Why separate RenderType and RenderPhase at all?
  • If they are kept separate, why have different names for things that seem to mean basically the same thing? ("WATER_AND_ICE" is a far worse name than "REFRACTIVE")
  • Why are TRANSLUCENT and BILLBOARD separated?
  • "REFRACTIVE" isn't an entirely appropriate name for alpha-blended rendering given that refraction only actually occurs for water.
The main distinctions that are actually necessary are whether the block needs back-face culling (this should be enabled for opaque blocks for efficiency, and could also be enabled for some alpha-reject blocks or disabled on flat, opaque blocks to alter their appearance), and whether it's transparent (i.e. blended, rendered with RefractiveReflectiveBlocksNode, rather than alpha-reject). Rendering opaque blocks with alpha-reject on wouldn't alter their appearance, and would add a presumably negligible amount of time for running the shader, but would allow some simplifications.

I propose:
  • Merge RenderPhase into RenderType.
  • Give RenderType the values ONE_SIDED, TWO_SIDED and REFRACTIVE (I'd prefer "TRANSLUCENT", but this would help avoid confusion with Block.isTranslucent, which also covers alpha-reject blocks).
  • Replace Block.isIce with something that explicitly refers to appearance or rendering for alpha-blended blocks, rather than a specific material, and set this flag on water, too. I'd prefer "translucent" for this, but that name is already taken. Possibly something like "semiTransparent" or just "alphaBlended". After PR #3481, this would just leave water and grass as rendering special-cases.
  • Maybe merge OpaqueBlocksNode and AlphaRejectBlocksNode, and just give it a boolean field for whether to apply back-face culling, then add one of each to the render graph. Set ALPHA_REJECT_FEATURE to always on for this node (or just get rid of the feature and set it always on in the shader, with a lower threshold so as to avoid problems with alpha-blended blocks). There are various trivial differences between these classes, so it's a little hard to tell whether there are any other important differences I'm missing.