Skip to content

Merge dev into main after syncing main#267

Merged
MichaelFisher1997 merged 62 commits intomainfrom
dev
Feb 10, 2026
Merged

Merge dev into main after syncing main#267
MichaelFisher1997 merged 62 commits intomainfrom
dev

Conversation

@MichaelFisher1997
Copy link
Collaborator

Summary

  • Sync dev with main first (merged main into dev, resolved all merge conflicts in favor of the latest dev implementations where overlap existed, and validated locally).
  • Carry forward the full dev line of work for rendering/world/input improvements (lighting overhaul follow-ups, TAA migration, Vulkan/RHI refactors, meshing/worldgen splits, and shadow/SSAO/LOD fixes).
  • Pre-push checks passed (zig fmt and full test suite via hooks) and branch is now ready for main integration.

Validation

  • nix develop --command zig build test
  • Pre-push hook checks passed during git push origin dev (formatting + full tests)

Linked issues/PRs referenced in dev commits

MichaelFisher1997 and others added 30 commits January 24, 2026 11:06
…218)

* feat: enable and stabilize LOD system (#216)

* feat: enable and stabilize LOD system

- Exposed lod_enabled toggle in settings and presets.
- Updated presets to enable LOD on HIGH/ULTRA.
- Optimized LOD performance by moving cleanup to throttled update.
- Fixed LOD-to-chunk transition masking in shader.
- Added unit tests for LOD settings application.

* refactor: apply SOLID principles and performance documentation to LOD system

- Introduced ILODConfig interface to decouple settings from LOD logic (Dependency Inversion).
- Extracted mask radius calculation into a pure function in ILODConfig for better testability (Single Responsibility).
- Documented the 4-frame throttle rationale in LODManager.
- Fixed a bug where redundant LOD chunks were being re-queued immediately after being unloaded.
- Added end-to-end unit test for covered chunk cleanup.

* fix: resolve build errors and correctly use ILODConfig interface

- Fixed type error in World.zig where LODManager was used as a function instead of a type.
- Updated all remaining direct radii accesses to use ILODConfig.getRadii() in WorldStreamer and WorldRenderer.
- Verified fixes with successful 'zig build test'.

* fix: remove redundant LOD cleanup from render path

- Removed redundant 'unloadLODWhereChunksLoaded' call from 'LODRenderer.render', fixing the double-call bug.
- Decoupled 'calculateMaskRadius' by adding it to the 'ILODConfig' vtable.
- Synchronized code with previous comments to ensure the throttled cleanup is now correctly localized to the update loop.

* Phase 2: Render Pipeline Modernization - Offscreen HDR Buffer & Post-Process Pass (#217)

* Phase 2: Render Pipeline Modernization - Offscreen HDR Buffer & Post-Process Pass

* Phase 2: Add synchronization barriers and improve resource lifecycle safety

* Phase 2: Add descriptor null-guards and configurable tone mapper selection

* Phase 2: Fix Vulkan offscreen HDR rendering and post-process pass initialization

Detailed changes:
- Decoupled main rendering pass from swapchain using an offscreen HDR buffer.
- Fixed initialization order to ensure HDR resources and main render pass are created before pipelines.
- Implemented dedicated post-process framebuffers for swapchain presentation.
- Added a fallback post-process pass for UI-only frames to ensure correct image layout transition.
- Fixed missing SSAO blur render pass creation.
- Added shadow 'regular' sampler and bound it to descriptor set binding 4.
- Added nullification of Vulkan handles after destruction to prevent validation errors.
- Improved swapchain recreation logic with pipeline rebuild tracking.
- Added debug logging for render pass and swapchain lifecycle.

* Implement FXAA, Bloom, and Velocity Buffer for Phase 3

* Phase 3 Fixes: Address review comments (memory leaks, hardcoded constants)

* feat: modularize FXAA and Bloom systems, add velocity buffer, and improve memory safety

* fix: add missing shadow sampler creation in createShadowResources

* fix: add missing G-Pass image/framebuffer creation and fix Bloom push constant stage flags

- Add G-Pass normal, velocity, and depth image creation that was lost during refactoring
- Create G-Pass framebuffer with all 3 attachments (normal, velocity, depth)
- Fix Bloom push constants to use VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT
  matching the pipeline layout definition

Fixes integration test failures with NULL VkImage and push constant validation errors.

* fix: resolve push constant and render pass ordering issues in Vulkan backend

* feat: add comprehensive branching strategy, PR templates, and contributing guidelines

- Add dev branch with branch protection (0 reviews, strict mode, linear history)
- Add 4 PR templates: feature, bug, hotfix, ci
- Add CONTRIBUTING.md with full workflow documentation
- Update build.yml to trigger on main and dev
- Add hotfix keywords to issue-labeler.json
- Add universal PR template as fallback

Resolves: Branching strategy and workflow improvements

* refactor: move FXAA/Bloom resource creation to systems, fix leaks

* fix: correct bloom descriptor binding count to fix validation error
* feat: enable and stabilize LOD system (#216)

* feat: enable and stabilize LOD system

- Exposed lod_enabled toggle in settings and presets.
- Updated presets to enable LOD on HIGH/ULTRA.
- Optimized LOD performance by moving cleanup to throttled update.
- Fixed LOD-to-chunk transition masking in shader.
- Added unit tests for LOD settings application.

* refactor: apply SOLID principles and performance documentation to LOD system

- Introduced ILODConfig interface to decouple settings from LOD logic (Dependency Inversion).
- Extracted mask radius calculation into a pure function in ILODConfig for better testability (Single Responsibility).
- Documented the 4-frame throttle rationale in LODManager.
- Fixed a bug where redundant LOD chunks were being re-queued immediately after being unloaded.
- Added end-to-end unit test for covered chunk cleanup.

* fix: resolve build errors and correctly use ILODConfig interface

- Fixed type error in World.zig where LODManager was used as a function instead of a type.
- Updated all remaining direct radii accesses to use ILODConfig.getRadii() in WorldStreamer and WorldRenderer.
- Verified fixes with successful 'zig build test'.

* fix: remove redundant LOD cleanup from render path

- Removed redundant 'unloadLODWhereChunksLoaded' call from 'LODRenderer.render', fixing the double-call bug.
- Decoupled 'calculateMaskRadius' by adding it to the 'ILODConfig' vtable.
- Synchronized code with previous comments to ensure the throttled cleanup is now correctly localized to the update loop.

* Phase 4: Implement GPU Profiling, Timing Overlay, and Preset Rebalancing

* fix: keep UI visible after post-processing and stabilize LOD threading
- fix(lod): implemented availability-based LOD transitions to eliminate horizon gaps
- fix(vulkan): resolved clear value and descriptor layout validation errors in Medium+ presets
- fix(lighting): boosted sky/cloud radiance to match PBR terrain and reduced fog gloom
- fix(ui): restored and thickened block selection outline in HDR pass
- fix(shadows): corrected Reverse-Z depth bias to eliminate acne on near blocks
- feat(hud): added LOD count to debug overlay
…xtures (#222)

* feat: implement visual polish including dithered LOD transitions, improved AO, and grid-free textures

- Implement screen-space dithered crossfading for LOD transitions
- Add distance-aware voxel AO to eliminate dark rectangular artifacts on distant terrain
- Disable texture atlas mipmapping to remove visible block boundary grid lines
- Enhance block selection outline thickness and expansion for better visibility
- Pass mask_radius from vertex to fragment shader for precise transition control

* fix: add missing bayerDither4x4 function and clean up magic numbers in terrain shader

- Implement missing bayerDither4x4 function in fragment shader
- Add missing vMaskRadius input declaration to fragment shader
- Extract LOD_TRANSITION_WIDTH and AO_FADE_DISTANCE to constants
- Remove trailing whitespace in UV calculation
- Fix shader compilation error introduced in previous commit

* fix: restore missing shadows and fix broken lighting logic in terrain shader

- Rewrite terrain fragment shader lighting logic to fix broken brackets and scope issues
- Ensure totalShadow is applied to all lighting branches (Legacy, PBR, and non-PBR)
- Clean up variable naming to avoid shadowing uniform block names
- Maintain previous visual polish fixes (LOD dithering, distance-aware AO, and grid-free textures)

* fix(graphics): Restore and optimize shadows, add debug view

- Fixed shadow rendering by correcting reverse-Z bias direction in shadow_system.zig
- Improved shadow visibility by masking ambient occlusion (reduced ambient by 80% in shadow)
- Optimized shadow resolution defaults (High: 4096->2048) for better performance (~12ms frame time)
- Added 'G' key toggle for Red/Green shadow debug view
- Fixed input/settings synchronization on app startup to ensure correct RHI state
- Fixed shadow acne by increasing depth bias slope factor

* chore: remove temporary test output files
* Refactor: Relocate drawDebugShadowMap to Debug Overlay System

* Refactor: Address code review comments for Debug Overlay refactor

* Fix: Shadow sampler initialization order and safety in destroyTexture

* Polish: Add InvalidImageView error and doc comments for Debug Overlay

* Docs: Add documentation for registerExternalTexture and DebugShadowOverlay

* Test: Add unit test for ResourceManager.registerExternalTexture validation
* refactor: relocate computeSSAO to dedicated SSAOSystem

- Introduced ISSAOContext in rhi.zig to follow interface segregation.
- Created SSAOSystem in vulkan/ssao_system.zig to encapsulate SSAO resources and logic.
- Updated Vulkan backend to integrate the new system and implement ISSAOContext.
- Refactored RenderGraph and mocks to use the new segregated interface.
- Closes #225

* refactor(ssao): improve SSAOSystem implementation based on PR feedback

- Extracted initialization phases into helper functions (SRP).
- Fixed misnamed command_pool parameter type.
- Added error handling for vkMapMemory.
- Improved shader module cleanup using defer and errdefer.
- Standardized error handling style for Vulkan calls.

* refactor(ssao): final polish of SSAOSystem implementation

- Extracted kernel and noise constants.
- Standardized shader path constants.
- Improved parameter naming and error checking.
- Added unit test for SSAO parameter defaults.
- Verified all 181 tests pass.

* fix(integration): resolve compilation errors and apply final polish

- Fixed Mat4.inverse() call in render_graph.zig.
- Removed stray ssao_kernel_ubo references in rhi_vulkan.zig.
- Fixed VulkanDevice mutability in SSAOSystem.init.
- Applied all code quality improvements from PR review.

* fix(rhi): resolve compilation and logic errors in SSAO refactor

- Implemented registerNativeTexture in ResourceManager to support externally managed images.
- Fixed double-free in ResourceManager.deinit by checking for memory ownership.
- Fixed TextureFormat usage (.red instead of .r8_unorm).
- Fixed stray SSAO resource references in rhi_vulkan.zig.
- Restored main descriptor set updates for SSAO map in rhi_vulkan.zig.
- Added missing initial layout transitions for SSAO images.

* refactor(graphics): final polish and standardization of post-process systems

- Introduced shader_registry.zig to centralize and de-duplicate shader paths.
- Removed redundant vkQueueWaitIdle in SSAOSystem texture initialization.
- Added internal unit tests for SSAOSystem (noise and kernel generation).
- Merged latest dev changes and resolved vtable conflicts.
- Standardized error handling and resource cleanup across SSAO, Bloom, and FXAA systems.

* fix(ssao): restore queue wait before freeing upload command buffer

Restored 'vkQueueWaitIdle' in SSAOSystem.initNoiseTexture to ensure the upload command buffer
is no longer in use by the GPU before it is freed. This fixes a validation error and
potential segmentation fault during initialization.
Fixes two critical energy conservation violations in PBR lighting:

1. Sun emission missing π division (CRITICAL)
   - Direct lighting was 3.14x too bright because sun color
     was not divided by π while BRDF diffuse term already was
   - Added / PI division to all sun color calculations (4 locations):
     * Volumetric lighting (line 242)
     * PBR direct lighting (line 453)
     * Non-PBR blocks direct lighting (line 486)
     * LOD mode direct lighting (line 519)
   - This reduces direct lighting energy to physically correct levels

2. IBL environment map not pre-filtered
   - Environment map was sampled at fixed mip level 8.0
     regardless of surface roughness
   - Added MAX_ENV_MIPS = 8.0 constant
   - Now samples mip level based on surface roughness:
     * PBR blocks: envMipLevel = roughness * 8.0
     * Non-PBR blocks: envMipLevel = 0.5 * 8.0
   - Rough surfaces get blurrier ambient reflections
   - Smooth surfaces get sharper ambient reflections

Impact:
- Sunlit surfaces are ~3.14x less bright (physically correct)
- Ambient reflections now properly vary with roughness
- Tone-mapping handles reduced energy appropriately
- Shadows more visible in sunlit areas

Fixes #230
- Replaced magic numbers (3.0, 4.0, 0.5, 8.0) with documented constants
- Refactored terrain.frag main() into focused functions (calculatePBR, calculateNonPBR, calculateLOD)
- Removed duplicate/dead code in terrain.frag lighting logic
- Corrected GlobalUniforms comment for pbr_params.w
- Verified removal of HUD notification spam in world.zig

Addresses code quality issues identified in PR review for #230.
…vation

- Extracted duplicate IBL sampling logic into sampleIBLAmbient()
- Added descriptive comments for MAX_ENV_MIP_LEVEL and SUN_PBR_MULTIPLIER constants
- Increased epsilon to 0.001 in BRDF denominators to improve numerical stability
- Improved naming consistency for albedo/vColor in main dispatch
- Added comment explaining vMaskRadius usage scope
- Cleaned up minor inconsistencies in rhi_vulkan.zig and world.zig
…rain shader

- Unified IBL ambient sampling via sampleIBLAmbient()
- Extracted BRDF evaluation into computeBRDF() for PBR clarity
- Consolidated cascade blending logic into calculateCascadeBlending()
- Standardized legacy lighting paths into calculateLegacyDirect()
- Documented physics justification for SUN_RADIANCE_TO_IRRADIANCE constant
- Extracted IBL_CLAMP_VALUE and VOLUMETRIC_DENSITY_SCALE constants
- Renamed calculateShadow to calculateShadowFactor for naming consistency
- Improved numerical stability by using 0.001 epsilon in BRDF denominators

Refinement of #230 fixes based on PR review.
- Standardized all lighting functions to compute* naming pattern
- Extracted IBL_CLAMP_VALUE and VOLUMETRIC_DENSITY_SCALE constants
- Consolidated legacy lighting logic into computeLegacyDirect()
- Improved physics derivation documentation for sun radiance multipliers
- Refactored monolithic main() to reduce nesting and improve readability
- Verified numerical stability with consistent 0.001 epsilon

Final polish for issue #230.
- Extracted remaining magic numbers into documented constants (IBL_CLAMP, VOLUMETRIC_DENSITY_FACTOR, etc.)
- Consolidated legacy lighting intensity multipliers
- Standardized all lighting functions to compute* naming convention
- Added detailed physics derivation comments for normalization factors
- Improved numerical stability in BRDF calculations

Final polish of #230.
- Renamed computeCascadeBlending to computeShadowCascades for clarity
- Extracted remaining magic numbers (DIELECTRIC_F0, COOK_TORRANCE_DENOM_FACTOR, VOLUMETRIC_DENSITY_FACTOR)
- Documented physics justification for radiance-to-irradiance conversion factor
- Standardized all function naming to compute* pattern
- Consolidated legacy and LOD lighting intensity constants (LEGACY_LIGHTING_INTENSITY, LOD_LIGHTING_INTENSITY)
- Re-verified energy conservation normalization factors across all lighting paths.
- Restored SUN_VOLUMETRIC_INTENSITY constant (3.0) for LOD/Volumetric lighting
- Fixed syntax error (duplicate code block/dangling brace)
- Verified shader compilation and project build
- Ensured legacy and LOD lighting paths use correct, distinct multipliers
- Restored missing getVolShadow function definition
- Removed duplicate/broken code blocks causing syntax errors
- Verified shader compilation and energy conservation logic
- Finalized refactoring for issue #230
… and 16-tap PCF

- Implemented high-quality 16-tap Poisson disk PCF filtering for smooth shadow edges
- Corrected shadow pipeline to use Reverse-Z (Near=1.0, Far=0.0) for maximum precision
- Refined shadow bias system with per-cascade scaling and slope-adaptive bias
- Optimized Vulkan memory management by implementing persistent mapping for all host-visible buffers
- Fixed Vulkan validation errors caused by frequent map/unmap operations
- Added normal offset bias in shadow vertex shader to eliminate self-shadowing artifacts
- Integrated stable cascade selection based on Euclidean distance
…adable Settings (#238)

* Fix keymap system bugs: G key hardcoding and F3 conflict

Fixes #235: Replaces hardcoded G key check in world.zig with input mapper action.

Fixes #236: Resolves F3 conflict by adding toggle_timing_overlay action (F4 default) and updating app.zig.

* Address code review: Remove redundant default key comments

* Implement human-readable JSON format for keybindings (V3 settings)

Fixes #237: Migrates from array-based to object-based JSON format with action names as keys.

* Address review: Add debounce logic and migration warnings

Adds explicit 200ms debounce to debug toggles in App and WorldScreen.

Adds warning log when legacy settings have more bindings than supported.

* Enable InputSettings unit tests
- Fix memory management bug in shadow pipeline recreation
- Add error logging for failed UBO memory mapping
- Optimize CSM matrix inverse performance
- Fix cascade split bounding sphere bug (last_split update)
- Stabilize and refine shadow bias parameters
- Implemented safe pipeline recreation in rhi_vulkan.zig to prevent memory bugs
- Added error logging for UBO memory mapping failures in descriptor_manager.zig
- Optimized CSM performance by caching the inverse camera view matrix
- Re-verified and stabilized shadow cascade bounding sphere logic
- Cleaned up redundant code and ensured SOLID principle compliance
MichaelFisher1997 and others added 11 commits February 7, 2026 03:02
…er (#243) (#259)

Fix cascade caching race condition by using pointer-based shared storage
so all 4 shadow passes use identical matrices within a frame. Add
float32 precision guard for texel snapping at large world coordinates.
Add shader-side NaN guard for cascade split selection. Add 8 unit tests
for shadow cascade validation, determinism, and edge cases.
* feat(lighting): Complete Phases A & C of Modern Lighting Overhaul (#143)

This commit implements colored block lights and post-processing effects,
completing phases A and C of issue #143. Phase B (LPV) is tracked in #260.

## Phase A: Colored Block Light System
- Add torch block (ID: 45) with warm orange emission (RGB: 15, 11, 6)
- Add lava block (ID: 46) with red-orange emission (RGB: 15, 8, 3)
- Extend existing RGB-packed light propagation system
- Update block registry with textures, transparency, and render pass settings
- Torch and lava now emit colored light visible in-game

## Phase C: Post-Processing Stack
- Implement vignette effect with configurable intensity
- Implement film grain effect with time-based animation
- Add settings: vignette_enabled, vignette_intensity, film_grain_enabled, film_grain_intensity
- Full UI integration in Graphics Settings screen
- Real-time parameter updates via RHI interface

## Technical Changes
- Modified: src/world/block.zig (new block types)
- Modified: src/world/block_registry.zig (light emission, properties)
- Modified: src/engine/graphics/resource_pack.zig (texture mappings)
- Modified: assets/shaders/vulkan/post_process.frag (vignette, grain)
- Modified: src/engine/graphics/vulkan/post_process_system.zig (push constants)
- Modified: src/game/settings/data.zig (new settings)
- Modified: src/game/screens/graphics.zig (UI handlers)
- Modified: src/engine/graphics/rhi.zig (new RHI methods)
- Modified: src/engine/graphics/rhi_vulkan.zig (implementations)
- Modified: src/engine/graphics/vulkan/rhi_context_types.zig (state storage)
- Modified: src/engine/graphics/vulkan/rhi_pass_orchestration.zig (push constants)

Closes #143 (partially - Phase B tracked in #260)

* fix(settings): disable vignette and film grain by default

Users expect a clean, modern look by default. These effects are now
opt-in via the Graphics Settings menu.

Fixes review feedback on PR #261

* fix(blocks): add missing textures and fix lava properties

Critical fixes for PR #261:

## Missing Textures (CRITICAL)
- Add assets/textures/default/torch.png (orange placeholder)
- Add assets/textures/default/lava.png (red placeholder)
- Prevents runtime texture loading failures

## Lava Block Properties (HIGH)
Fix lava to behave as a proper fluid/light source:
- is_solid: false (was true) - allows light propagation and player movement
- is_transparent: true - allows light to pass through
- is_fluid: true - enables fluid physics and rendering
- render_pass: .fluid - proper fluid rendering pipeline

These changes ensure lava:
- Emits colored light correctly (RGB: 15, 8, 3)
- Propagates light to surrounding blocks
- Renders with proper fluid transparency
- Behaves consistently with water fluid mechanics

Fixes review feedback on PR #261
Add step to fetch previous opencode-agent reviews using gh API
Include previous reviews in prompt context
Update prompt instructions to verify previous issues are fixed
Add explicit instructions to acknowledge fixes with ✅ markers
Only report unresolved issues, not already-fixed ones
Remove single quotes from heredoc delimiter which GitHub Actions doesn't support
Rewrite to build content in variable first, then use printf for proper handling
* feat(lighting): Complete Phases A & C of Modern Lighting Overhaul (#143)

This commit implements colored block lights and post-processing effects,
completing phases A and C of issue #143. Phase B (LPV) is tracked in #260.

## Phase A: Colored Block Light System
- Add torch block (ID: 45) with warm orange emission (RGB: 15, 11, 6)
- Add lava block (ID: 46) with red-orange emission (RGB: 15, 8, 3)
- Extend existing RGB-packed light propagation system
- Update block registry with textures, transparency, and render pass settings
- Torch and lava now emit colored light visible in-game

## Phase C: Post-Processing Stack
- Implement vignette effect with configurable intensity
- Implement film grain effect with time-based animation
- Add settings: vignette_enabled, vignette_intensity, film_grain_enabled, film_grain_intensity
- Full UI integration in Graphics Settings screen
- Real-time parameter updates via RHI interface

## Technical Changes
- Modified: src/world/block.zig (new block types)
- Modified: src/world/block_registry.zig (light emission, properties)
- Modified: src/engine/graphics/resource_pack.zig (texture mappings)
- Modified: assets/shaders/vulkan/post_process.frag (vignette, grain)
- Modified: src/engine/graphics/vulkan/post_process_system.zig (push constants)
- Modified: src/game/settings/data.zig (new settings)
- Modified: src/game/screens/graphics.zig (UI handlers)
- Modified: src/engine/graphics/rhi.zig (new RHI methods)
- Modified: src/engine/graphics/rhi_vulkan.zig (implementations)
- Modified: src/engine/graphics/vulkan/rhi_context_types.zig (state storage)
- Modified: src/engine/graphics/vulkan/rhi_pass_orchestration.zig (push constants)

Closes #143 (partially - Phase B tracked in #260)

* fix(settings): disable vignette and film grain by default

Users expect a clean, modern look by default. These effects are now
opt-in via the Graphics Settings menu.

Fixes review feedback on PR #261

* fix(blocks): add missing textures and fix lava properties

Critical fixes for PR #261:

## Missing Textures (CRITICAL)
- Add assets/textures/default/torch.png (orange placeholder)
- Add assets/textures/default/lava.png (red placeholder)
- Prevents runtime texture loading failures

## Lava Block Properties (HIGH)
Fix lava to behave as a proper fluid/light source:
- is_solid: false (was true) - allows light propagation and player movement
- is_transparent: true - allows light to pass through
- is_fluid: true - enables fluid physics and rendering
- render_pass: .fluid - proper fluid rendering pipeline

These changes ensure lava:
- Emits colored light correctly (RGB: 15, 8, 3)
- Propagates light to surrounding blocks
- Renders with proper fluid transparency
- Behaves consistently with water fluid mechanics

Fixes review feedback on PR #261

* feat(lighting): add LPV compute GI with debug profiling

* fix(lighting): harden LPV shader loading and propagation tuning

* fix(lighting): address LPV review blockers

* fix(lighting): clarify 3D texture config and LPV debug scaling

* chore(lighting): polish LPV docs and overlay sizing

* docs(lighting): clarify LPV constants and 3D mipmap behavior

* docs(vulkan): clarify createTexture3D config handling

* perf(lighting): gate LPV debug overlay work behind toggle
…r grading, 3D dummy texture fix (#264)

* feat(lighting): add 3D dummy texture for LPV sampler3D bindings, PCSS soft shadows, SH L1 LPV with occlusion, and LUT color grading

Implement the full lighting overhaul (phases 4-6):
- PCSS: Poisson-disk blocker search with penumbra-based variable-radius PCF
- LPV: native 3D textures, SH L1 directional encoding (3 channels), occlusion-aware propagation
- Post-process: LUT-based color grading with 32^3 neutral identity texture
- Fix Vulkan validation error on bindings 11-13 by creating a 1x1x1 3D dummy texture
  so sampler3D descriptors have a correctly-typed fallback before LPV initialization

Resolves #143

* fix(lighting): add host-compute barrier for SSBO uploads, match dummy 3D texture format, clamp LPV indirect

- Add VK_PIPELINE_STAGE_HOST_BIT -> COMPUTE_SHADER barrier before LPV
  dispatch to guarantee light buffer and occlusion grid visibility
- Change 3D dummy texture from .rgba (RGBA8) to .rgba32f with zero data
  to match LPV texture format and avoid spurious SH contribution
- Clamp sampleLPVAtlas output to [0, 2] to prevent overexposure from
  accumulated SH values
Make LPV grid reconfiguration transactional with rollback, surface occlusion allocation failures, and clean up partial LOD manager init on allocation errors. Add runtime LOD bridge context checks, support larger shader module loads, and return UnsupportedFace instead of unreachable in greedy meshing.
* settings: add initial TAA config scaffold

* graphics: add Halton jitter plumbing for temporal AA

* graphics: scaffold TAA resources and render-graph stage

* graphics: implement TAA resolve and history feedback

* graphics: force single-sample main pass path

* settings: migrate AA UX toward TAA controls

* world/graphics: split cutout geometry into dedicated mesh pass

* settings: expose configurable TAA blend and rejection

* build/settings: validate TAA shaders and tune preset defaults
@github-actions github-actions bot added documentation Improvements or additions to documentation engine game world build shaders labels Feb 9, 2026
@opencode-agent
Copy link
Contributor

opencode-agent bot commented Feb 9, 2026

Now I have a comprehensive understanding of the changes. Let me provide the structured code review.


📋 Summary

Linked Issues Referenced: #201, #218, #219, #222, #227, #228, #229, #230, #238, #242, #243, #250, #251, #252, #253, #254, #255, #257, #258, #259, #261, #262, #264, #266

This PR is a dev → main merge consolidating extensive rendering improvements including a new Temporal Anti-Aliasing (TAA) system, camera jitter integration, shadow/LOD rendering fixes, and RHI refactoring. The implementation quality is high with proper Vulkan resource management, Halton sequence jittering, and thoughtful separation of concerns. All validation checks (zig fmt, test suite) have passed according to the PR description.

🔴 Critical Issues (Must Fix - Blocks Merge)

None identified

⚠️ High Priority Issues (Should Fix)

None identified

💡 Medium Priority Issues (Nice to Fix)

[MEDIUM] src/engine/graphics/vulkan/taa_system.zig:15-21 - Missing explicit initialization for output_texture swap
Confidence: Medium
Description: The output_texture field is initialized to 0 in the struct definition, but it's only properly set in ensureResources() after history textures are created. If compute() is called before resources are ensured, the output_texture remains 0 which could cause issues if accessed prematurely.
Impact: Low risk due to guard checks, but could lead to confusion or subtle bugs if the output texture handle is used before initialization.
Suggested Fix: Consider adding an assertion in compute() that self.output_texture != 0 or ensure resources are always created before compute is called.

[MEDIUM] src/engine/graphics/vulkan/taa_system.zig:63-65 - Error defer order could leak texture on second allocation failure
Confidence: Medium
Description: Line 64 has errdefer self.destroyHistoryTextures(resources) but if line 65 fails, only the first texture handle is stored and the second allocation failure won't clean up the first successfully allocated texture.
Impact: Memory leak in edge case where second texture allocation fails.
Suggested Fix: Store the first texture in a temporary variable and use a scope-guarded cleanup, or move errdefer before the second allocation attempt.

self.history_textures[0] = try resources.createTexture(...);
errdefer resources.destroyTexture(self.history_textures[0]);  // Guard first texture
self.history_textures[1] = try resources.createTexture(...);

ℹ️ Low Priority Suggestions (Optional)

[LOW] src/engine/graphics/camera.zig:15-20 - Hardcoded Halton sequence lacks documentation link
Confidence: Low
Description: The 4-tap Halton(2,3) sequence is implemented but there's no reference to how these values were computed or validated.
Suggested Fix: Add a comment with a reference to the Halton sequence generator or expected distribution properties for future maintainers.

[LOW] src/engine/graphics/vulkan/shader_registry.zig:15-16 - TAA reuses post_process.vert instead of dedicated vertex shader
Confidence: Low
Description: TAA_VERT points to post_process.vert.spv instead of the newly added taa.vert.spv.
Impact: May be intentional since vertex shaders are identical, but could cause confusion.
Suggested Fix: Either update to use taa_vert.spv or add a comment explaining the reuse.

[LOW] assets/shaders/vulkan/taa.frag:27 - Reset history condition could be more precise
Confidence: Low
Description: The condition checks for UV bounds individually but could use any() or all() for clarity.
Suggested Fix:

if (taa.reset_history > 0.5 || any(lessThan(history_uv, vec2(0.0))) || any(greaterThan(history_uv, vec2(1.0))))

📊 SOLID Principles Score

Principle Score Notes
Single Responsibility 8/10 TAASystem handles TAA compute, history management, and Vulkan resources cleanly. Camera jitter logic is well-separated.
Open/Closed 9/10 New TAA system extends RHI via interfaces without modifying existing code. Settings extend metadata pattern.
Liskov Substitution 9/10 RHI interface additions (computeTAA, setTAABlendFactor) follow existing patterns and maintain backward compatibility.
Interface Segregation 8/10 IRenderContext VTable continues to grow but TAA methods are appropriately scoped. Consider splitting further in future.
Dependency Inversion 9/10 TAASystem depends on RHI abstractions, not concrete Vulkan types directly. Uses generic resources parameter.
Average 8.6 Strong adherence to SOLID principles throughout the changes.

🎯 Final Assessment

Overall Confidence Score: 88%

Confidence Breakdown:

  • Code Quality: 90% (Clean, idiomatic Zig with proper error handling and resource management)
  • Completeness: 85% (TAA system is feature-complete with settings integration, minor shader registry inconsistency noted)
  • Risk Level: 15% (Low risk - follows established patterns, proper cleanup, validation passed)
  • Test Coverage: 85% (Build validation includes new shaders, settings have metadata)

Merge Readiness:

  • All critical issues resolved
  • SOLID average score >= 6.0
  • Overall confidence >= 60%
  • No security concerns
  • Tests present and passing (PR indicates validation passed)

Verdict:

MERGE WITH FIXES

The PR is high-quality and ready to merge after addressing the medium-priority error handling issue in taa_system.zig (line 63-65) to prevent potential resource leaks. The shader registry path inconsistency should also be verified as intentional.

New%20session%20-%202026-02-09T22%3A50%3A30.469Z
opencode session  |  github run

@MichaelFisher1997 MichaelFisher1997 marked this pull request as draft February 9, 2026 23:01
@github-actions github-actions bot added the ci label Feb 9, 2026
@MichaelFisher1997 MichaelFisher1997 marked this pull request as ready for review February 9, 2026 23:27
@opencode-agent
Copy link
Contributor

opencode-agent bot commented Feb 9, 2026

Based on my analysis of the code and comparison with the previous review, I can now provide a comprehensive review.


📋 Summary

Linked Issues Referenced: #201, #218, #219, #222, #227, #228, #229, #230, #238, #242, #243, #250, #251, #252, #253, #254, #255, #257, #258, #259, #261, #262, #264, #266

This PR consolidates extensive rendering improvements from dev into main, including a complete Temporal Anti-Aliasing (TAA) system with camera jitter integration, proper RHI abstractions for TAA, settings integration, and various graphics pipeline fixes. The code quality is high with proper Zig idioms, error handling, and Vulkan resource management.

🔴 Critical Issues (Must Fix - Blocks Merge)

None identified

⚠️ High Priority Issues (Should Fix)

None identified

💡 Medium Priority Issues (Nice to Fix)

[MEDIUM] src/engine/graphics/vulkan/taa_system.zig:63-68 - Error defer order could leak texture on second allocation failure
Confidence: Medium
Description: The errdefer at line 68 only guards cleanup for both textures together via destroyHistoryTextures. However, if line 65 succeeds but line 66 fails, the first texture handle is stored in self.history_textures[0] but the errdefer will try to destroy history_0 (which is already stored) and also access self.history_textures[0] which now contains the same value. While this works due to the != 0 check in destroyHistoryTextures, it's fragile.
Impact: Potential double-free or logic error if cleanup logic changes.
Suggested Fix: Use a cleaner pattern with temporary storage:

const history_0 = try resources.createTexture(extent.width, extent.height, .rgba32f, config, null);
errdefer resources.destroyTexture(history_0);
const history_1 = try resources.createTexture(extent.width, extent.height, .rgba32f, config, null);

self.history_textures = .{ history_0, history_1 };
// Only set errdefer for both after both succeed
errdefer self.destroyHistoryTextures(resources);

ℹ️ Low Priority Suggestions (Optional)

[LOW] src/engine/graphics/vulkan/taa_system.zig:30 - Output texture initialized to 0 but used without explicit guards
Confidence: Low
Description: output_texture defaults to 0 and is only set properly after ensureResources() completes. While the compute() function has guards, explicit initialization or an assertion would be clearer.
Suggested Fix: Add assertion in compute(): std.debug.assert(self.output_texture != 0);

[FIXED] Previous issue: Hardcoded Halton sequence - Now has explanatory comment at lines 12-14 explaining the 4-tap Halton(2,3) sequence rationale.

📊 SOLID Principles Score

Principle Score Notes
Single Responsibility 9/10 TAASystem cleanly separates TAA logic, history management, and resource lifecycle. Camera jitter is well-isolated.
Open/Closed 9/10 TAA extends RHI via interface methods without modifying existing code paths. Settings use metadata pattern for extensibility.
Liskov Substitution 9/10 New RHI methods (computeTAA, setTAABlendFactor) follow existing patterns, maintaining interface consistency.
Interface Segregation 8/10 RHI VTable continues growing but TAA methods are appropriately scoped within IRenderContext.
Dependency Inversion 9/10 TAASystem depends on RHI abstractions (anytype resources), not concrete Vulkan types.
Average 8.8 Strong adherence to SOLID principles.

🎯 Final Assessment

Overall Confidence Score: 92%

Confidence Breakdown:

  • Code Quality: 95% (Excellent Zig idioms, proper error handling, comprehensive resource cleanup)
  • Completeness: 90% (Full TAA system with settings integration, shader validation, render graph integration)
  • Risk Level: 10% (Low risk - follows established patterns, validation passed per PR description)
  • Test Coverage: 90% (Build validation includes new shaders, test suite passed)

Merge Readiness:

  • All critical issues resolved
  • SOLID average score >= 6.0 (8.8)
  • Overall confidence >= 60% (92%)
  • No security concerns
  • Tests present and passing (validated per PR)

Verdict:

MERGE

The PR is high-quality and ready for merge. The single medium-priority issue noted is a minor defensive coding improvement and doesn't block functionality. The TAA implementation is well-architected with proper resource management and follows project conventions.

New%20session%20-%202026-02-09T23%3A46%3A07.215Z
opencode session  |  github run

@opencode-agent
Copy link
Contributor

Now I have sufficient information to provide a comprehensive review. Let me compile the analysis:


📋 Summary

Linked Issues Referenced: #201, #218, #219, #222, #227, #228, #229, #230, #238, #242, #243, #250, #251, #252, #253, #254, #255, #257, #258, #259, #261, #262, #264, #266

This PR is a dev → main merge consolidating extensive rendering improvements including a complete Temporal Anti-Aliasing (TAA) system with camera jitter integration, RHI abstractions, settings integration, and various graphics pipeline fixes. The implementation is high quality with proper Vulkan resource management, Halton sequence jittering, and thoughtful separation of concerns. Pre-push validation checks passed.

Issues Addressed from Previous Reviews:

  • ✅ Camera Halton sequence now properly documented at lines 12-14
  • ✅ TAA shader paths correctly registered in shader_registry.zig
  • ✅ Fragment shader improved using any() for bounds checking

🔴 Critical Issues (Must Fix - Blocks Merge)

None identified

⚠️ High Priority Issues (Should Fix)

None identified

💡 Medium Priority Issues (Nice to Fix)

[MEDIUM] src/engine/graphics/vulkan/taa_system.zig:63-72 - Error defer pattern may cause double-free on cleanup
Confidence: Medium
Description: The error handling pattern creates a subtle issue. The first errdefer at line 64 guards history_0 destruction, and the second at line 66 guards history_1. However, the errdefer block at lines 69-71 that resets self.history_textures to zero will execute if createFramebuffers() fails (line 74). At that point, destroyHistoryTextures() may be called elsewhere expecting to destroy the textures via self.history_textures, but the handles have already been destroyed by the individual errdefers, leading to potential double-free or use-after-free.
Impact: Resource management inconsistency; could lead to Vulkan validation errors or crashes on resize/recreate operations.
Suggested Fix: Restructure to avoid overlapping cleanup responsibilities:

const history_0 = try resources.createTexture(extent.width, extent.height, .rgba32f, config, null);
errdefer resources.destroyTexture(history_0);
const history_1 = try resources.createTexture(extent.width, extent.height, .rgba32f, config, null);
errdefer resources.destroyTexture(history_1);

// Store in struct only after both allocations succeed
self.history_textures = .{ history_0, history_1 };

// Now use a single cleanup path via destroyHistoryTextures
errdefer self.destroyHistoryTextures(resources);

try self.createFramebuffers(vk, resources, extent);

ℹ️ Low Priority Suggestions (Optional)

None identified - all previously suggested low priority items have been addressed.

📊 SOLID Principles Score

Principle Score Notes
Single Responsibility 9/10 TAASystem cleanly separates TAA logic, history management, and resource lifecycle. Camera jitter is well-isolated from projection logic.
Open/Closed 9/10 TAA extends RHI via interface methods without modifying existing rendering paths. Settings use established metadata pattern.
Liskov Substitution 9/10 New RHI methods follow existing patterns, maintaining interface consistency. TAASystem can work with any resource manager implementing the expected interface.
Interface Segregation 8/10 RHI VTable continues growing appropriately. TAA methods are properly scoped within the rendering context.
Dependency Inversion 9/10 TAASystem depends on RHI abstractions (anytype resources), not concrete Vulkan types. Proper separation of concerns.
Average 8.8 Strong adherence to SOLID principles throughout the implementation.

🎯 Final Assessment

Overall Confidence Score: 92%

Confidence Breakdown:

  • Code Quality: 94% (Excellent Zig idioms, proper error handling patterns, comprehensive resource cleanup)
  • Completeness: 92% (Full TAA system with settings integration, proper shader validation, render graph integration)
  • Risk Level: 12% (Low risk - follows established patterns, validation passed per PR description)
  • Test Coverage: 90% (Build validation includes new shaders, test suite passed)

Merge Readiness:

  • All critical issues resolved
  • SOLID average score >= 6.0 (8.8 achieved)
  • Overall confidence >= 60% (92% achieved)
  • No security concerns
  • Tests present and passing (validated per PR description)

Verdict:

MERGE

The PR is high-quality and ready for merge. The single medium-priority issue noted is a defensive coding improvement that doesn't block functionality - the current implementation will work correctly in normal operation. The TAA implementation is well-architected with proper resource management, follows project conventions, and all previously reported issues have been addressed.

New%20session%20-%202026-02-10T00%3A13%3A23.308Z
opencode session  |  github run

@opencode-agent
Copy link
Contributor

Based on my analysis of the current code and comparison with previous reviews:


📋 Summary

Linked Issues Referenced: #201, #218, #219, #222, #227, #228, #229, #230, #238, #242, #243, #250, #251, #252, #253, #254, #255, #257, #258, #259, #261, #262, #264, #266

This PR merges extensive rendering improvements from dev to main, featuring a complete Temporal Anti-Aliasing (TAA) system with camera jitter integration, RHI abstractions, settings integration, and graphics pipeline enhancements. The implementation demonstrates high code quality with proper Zig idioms and Vulkan resource management.

Issues Addressed from Previous Reviews:

  • [FIXED] taa_system.zig error defer pattern (lines 63-72) - Now uses clean block scope pattern with proper cleanup
  • [FIXED] camera.zig Halton sequence documentation (lines 12-20) - Added explanatory comments for 4-tap sequence
  • [FIXED] shader_registry.zig TAA shader paths (lines 15-16) - Correctly points to dedicated taa.vert.spv
  • [FIXED] taa.frag reset history condition (line 27) - Now uses any() for cleaner bounds checking

🔴 Critical Issues (Must Fix - Blocks Merge)

All previously reported critical issues have been resolved.

None identified

⚠️ High Priority Issues (Should Fix)

None identified

💡 Medium Priority Issues (Nice to Fix)

None identified - all previously reported medium priority issues have been addressed.

ℹ️ Low Priority Suggestions (Optional)

None identified - all previously reported low priority items have been addressed.

📊 SOLID Principles Score

Principle Score Notes
Single Responsibility 9/10 TAASystem cleanly separates TAA logic, history management, and resource lifecycle. Camera jitter is well-isolated from projection logic.
Open/Closed 9/10 TAA extends RHI via interface methods without modifying existing rendering paths. Settings use established metadata pattern.
Liskov Substitution 9/10 New RHI methods follow existing patterns, maintaining interface consistency. TAASystem can work with any resource manager implementing the expected interface.
Interface Segregation 8/10 RHI VTable continues growing appropriately. TAA methods are properly scoped within the rendering context.
Dependency Inversion 9/10 TAASystem depends on RHI abstractions (anytype resources), not concrete Vulkan types. Proper separation of concerns.
Average 8.8 Strong adherence to SOLID principles throughout the implementation.

🎯 Final Assessment

Overall Confidence Score: 94%

Confidence Breakdown:

  • Code Quality: 95% (Excellent Zig idioms, proper error handling patterns, comprehensive resource cleanup)
  • Completeness: 93% (Full TAA system with settings integration, proper shader validation, render graph integration)
  • Risk Level: 8% (Very low risk - follows established patterns, validation passed per PR description)
  • Test Coverage: 90% (Build validation includes new shaders, test suite passed)

Merge Readiness:

  • All critical issues resolved
  • SOLID average score >= 6.0 (8.8 achieved)
  • Overall confidence >= 60% (94% achieved)
  • No security concerns
  • Tests present and passing (validated per PR description)

Verdict:

MERGE

The PR is production-ready. All previously reported issues have been successfully addressed, the TAA implementation is well-architected with proper resource management, and the code follows project conventions throughout. The error handling in taa_system.zig now uses a clean block scope pattern that properly guards both texture allocations, and all documentation concerns have been resolved.

New%20session%20-%202026-02-10T03%3A20%3A39.442Z
opencode session  |  github run

@MichaelFisher1997 MichaelFisher1997 merged commit 116b158 into main Feb 10, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant