Skip to content

[Batch 1] Billboard/cross-model rendering for vegetation #373

@MichaelFisher1997

Description

@MichaelFisher1997

Summary

Flowers, tall grass, saplings, bamboo, and dead bushes are currently rendered as solid cubes in the cutout render pass. They should use a cross/billboard model (2 diagonal quads) like Minecraft. This reduces vertex count by ~70% for vegetation blocks and dramatically improves visual quality.

Current Behavior

All 46 block types use the same cube meshing path in greedy_mesher.zig. The block registry has a render_pass field (.solid, .cutout, .fluid, .translucent) but no shape distinction. Flowers and grass get 6 cube faces with the texture on all sides — they look like cubes with a flower texture.

Target Behavior

Add a RenderShape enum to block definitions:

  • .cube — standard 6-face cube (current behavior, default)
  • .cross — 2 diagonal quads crossing at center (flowers, saplings, dead bush)
  • .tall_cross — 2 tall diagonal quads, height = 2 blocks (tall grass, bamboo may use this or cross)

Affected blocks:

Block Shape Notes
flower_red cross
flower_yellow cross
tall_grass cross Slightly shorter quad
dead_bush cross
acacia_sapling cross
bamboo cross Thin variant
torch cross Single thin quad pair, emissive

Implementation Plan

Step 1: Add RenderShape to block registry

In src/world/block_registry.zig:

  • Add render_shape field to BlockDefinition struct
  • Populate for all blocks (.cube default, .cross for vegetation)
  • Expose helper: getBlockDefinition(block).render_shape

Step 2: Cross-pattern vertex generation

In src/world/chunk_mesh.zig or meshing/greedy_mesher.zig:

  • When encountering a .cross block, skip the normal cube face generation
  • Instead emit 2 quads forming an X shape:
    Quad 1: (-0.15, 0, -0.15) → (0.15, 1, 0.15) diagonal
    Quad 2: (-0.15, 0,  0.15) → (0.15, 1, -0.15) diagonal
    
  • Both quads have double-sided faces (4 triangles total, 12 vertices with front+back)
  • UV mapping: full texture on both quads
  • AO: can use simple vertex AO or disable for cross shapes
  • Biome tint applied via vertex color

Step 3: Greedy mesher skip

  • greedy_mesher.zig should NOT merge cross blocks with adjacent cross blocks
  • Each cross block is meshed independently (4 triangles is already minimal)
  • Cross blocks still go through the cutout pass for alpha testing

Step 4: Torch special case

  • Torch could use a single thin quad or a 3-cross pattern
  • Must preserve emissive block light (already handled by block registry)

Files to Modify

  • src/world/block_registry.zig — add RenderShape enum, populate per block
  • src/world/chunk_mesh.zig — branch on render_shape during mesh building
  • src/world/meshing/greedy_mesher.zig — skip greedy merge for cross blocks

Testing

  • Cross blocks render as X-shaped billboards
  • Cube blocks unaffected (no regression)
  • Biome tinting still applied (grass, leaves)
  • Torch renders and emits light
  • Cutout alpha testing works on cross quads
  • No z-fighting between cross quads
  • Block outline still highlights cross blocks correctly

Impact

~70% fewer vertices for vegetation blocks. Visual quality improvement — the #1 visual sore thumb in the current engine.

Roadmap: docs/PERFORMANCE_ROADMAP.md — Batch 1, Issue 1C

Metadata

Metadata

Assignees

No one assigned

    Labels

    batch-1Batch 1: Foundation (no dependencies)documentationImprovements or additions to documentationenhancementNew feature or requesthotfixquestionFurther information is requestedshadersworld

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions