Skip to content

feat: Modern Lighting System Overhaul #143

@MichaelFisher1997

Description

@MichaelFisher1997

Overview

Complete overhaul of the lighting system to achieve modern, realistic rendering quality on par with mainstream game engines. This addresses current issues with washed-out colors, visual anomalies, and flat/unrealistic lighting.

Current Problems

Problem Cause Solution
Washed out colors Improper sRGB handling + weak tone mapping Fix color pipeline + better grading
Visual anomalies Flat normals + precision issues in IBL Vertex AO + improved sampling
Low quality feel No ambient occlusion, flat ambient SSAO + Voxel AO + Colored GI
Unrealistic No light bounce, harsh transitions LPV/Colored propagation + soft shadows

Target Specifications

  • GPU Memory: 8GB VRAM target (medium settings)
  • Art Direction: Realistic (similar to modern Minecraft shaders)
  • Colored Lights: Yes - torches, lava, glowstone should cast colored light

Implementation Phases

Phase 0: Fix Color Pipeline (Foundation)

Goal: Fix washed-out colors before adding features

  • 0.1 Use VK_FORMAT_R8G8B8A8_SRGB for albedo textures (hardware decode)
  • 0.2 Remove manual pow(2.2) conversion in shader
  • 0.3 Replace ACES with AgX or Tony McMapface tone mapping
  • 0.4 Add exposure control uniform
  • 0.5 Fix IBL sampling - generate pre-filtered mip-mapped environment maps

Files: rhi_vulkan.zig, terrain.frag
Estimated: 2-3 hours | Impact: HIGH


Phase 1: Voxel Ambient Occlusion (Baked)

Goal: Add depth and definition to block geometry

Before:                    After:
┌─────────────┐           ┌─────────────┐
│             │           │▓▓▓       ▓▓▓│  <- Darker in corners
│             │           │▓           ▓│
│             │           │             │
└─────────────┘           └─────────────┘
  • 1.1 Calculate AO per-vertex during mesh generation (check 8 neighbors)
  • 1.2 Add ao: f32 to Vertex struct in rhi.zig
  • 1.3 Pass AO through vertex shader
  • 1.4 Multiply ambient by AO in fragment shader

Files: chunk_mesh.zig, rhi.zig, terrain.vert, terrain.frag
Estimated: 3-4 hours | Impact: VERY HIGH for voxels


Phase 2: Colored Block Light System

Goal: Torches cast orange, glowstone casts yellow, lava casts red-orange

Current system:

PackedLight = { sky: u4, block: u4 }  // 8 bits, intensity only

New system:

PackedLightRGB = { sky: u4, r: u4, g: u4, b: u4 }  // 20 bits
  • 2.1 Update PackedLight struct in chunk.zig to support RGB
  • 2.2 Add getLightEmissionRGB() to block.zig with color values:
    • Torch: { r: 15, g: 11, b: 6 } (warm orange)
    • Glowstone: { r: 15, g: 14, b: 10 } (warm yellow)
    • Lava: { r: 15, g: 8, b: 3 } (red-orange)
  • 2.3 Modify BFS propagation in generator.zig to propagate RGB
  • 2.4 Update mesh generation to encode RGB light per-vertex
  • 2.5 Update shader to use colored vBlockLight

Files: chunk.zig, block.zig, generator.zig, chunk_mesh.zig, terrain.frag
Estimated: 4-6 hours | Impact: HIGH (atmosphere)


Phase 3: Screen-Space Ambient Occlusion (SSAO)

Goal: Runtime AO for all geometry (complements baked voxel AO)

Algorithm: Scalable Ambient Obscurance (SAO)

  • Sample depth buffer in hemisphere around each pixel
  • Compare depths to detect occlusion
  • Blur result to reduce noise

New render passes:

1. Geometry Pass (existing) → Color + Depth + Normals
2. SSAO Pass (new) → AO texture
3. Blur Pass (new) → Blurred AO
4. Composite Pass (modified) → Final * AO
  • 3.1 Create G-buffer with normals output
  • 3.2 Create SSAO shader (ssao.frag)
  • 3.3 Create blur shader (ssao_blur.frag)
  • 3.4 Modify render graph in rhi_vulkan.zig
  • 3.5 Composite AO in final pass

Files: New shaders, rhi_vulkan.zig, render_graph.zig
Estimated: 6-8 hours | Impact: MEDIUM-HIGH


Phase 4: Soft Shadows (PCSS)

Goal: Shadows sharp near caster, soft at distance

Current: Fixed-size PCF kernel
New: Percentage-Closer Soft Shadows

float blockerDepth = findAverageBlockerDepth(shadowCoord);
float penumbraSize = (receiverDepth - blockerDepth) / blockerDepth * lightSize;
float shadow = PCF(shadowCoord, penumbraSize);
  • 4.1 Add blocker search pass
  • 4.2 Calculate penumbra size
  • 4.3 Variable-size PCF kernel
  • 4.4 Add light size uniform for artistic control

Files: terrain.frag
Estimated: 3-4 hours | Impact: MEDIUM


Phase 5: Light Propagation Volumes (LPV)

Goal: Cheap real-time global illumination

How it works:

  1. Inject direct light into 3D grid (64³)
  2. Propagate light to neighbors using spherical harmonics
  3. Sample grid in shader for indirect lighting
Sun hits red block → Grid cell stores red light
Propagate → Nearby cells get dimmer red
Sample in shader → Objects near red block get red ambient
  • 5.1 Create LPV 3D texture (RGBA16F, ~16MB for 64³)
  • 5.2 Create light injection compute shader
  • 5.3 Create propagation compute shader (4 iterations)
  • 5.4 Sample LPV in terrain.frag for indirect lighting
  • 5.5 Integrate with colored block light system

Files: New compute shaders, rhi_vulkan.zig, terrain.frag
Estimated: 10-15 hours | Impact: VERY HIGH (game-changer)


Phase 6: Post-Processing Stack

Goal: Final polish and artistic control

  • 6.1 Bloom - Glow around light sources
  • 6.2 Color Grading - LUT-based color adjustment
  • 6.3 Vignette - Subtle edge darkening
  • 6.4 Film Grain (optional) - Subtle noise for realism

Files: New post-process shaders, rhi_vulkan.zig
Estimated: 4-6 hours | Impact: MEDIUM (polish)


Memory Budget (8GB VRAM target)

Resource Size Notes
Shadow cascades (3x 2048²) ~48 MB Existing
SSAO buffer (1080p) ~8 MB Half-res
LPV grid (64³ RGBA16F) ~16 MB Per-frame
Bloom mip chain ~20 MB 6 levels
Total new ~92 MB Well within budget

Timeline

Week Phase Deliverables
1 0 + 1 Fixed colors + Voxel AO
2 2 Colored block lights
3 3 + 4 SSAO + Soft shadows
4 5 Light Propagation Volumes
5 6 Post-processing polish

Acceptance Criteria

  • No washed-out colors - vibrant, saturated appearance
  • No visual artifacts from IBL sampling
  • Visible ambient occlusion in corners and crevices
  • Colored light from emissive blocks (torches, lava, glowstone)
  • Soft shadows that vary based on distance from caster
  • Indirect colored lighting from light bounces
  • Bloom around bright light sources
  • Performance target: 60fps @ 1080p on 8GB VRAM GPU

Labels

enhancement, graphics, lighting

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingenhancementNew feature or requestquestionFurther information is requested

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions