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:
I propose:
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.
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.