-
Notifications
You must be signed in to change notification settings - Fork 0
[Batch 6] Dynamic resolution rendering #392
Copy link
Copy link
Open
Labels
batch-6Batch 6: CapstoneBatch 6: CapstonedocumentationImprovements or additions to documentationImprovements or additions to documentationengineenhancementNew feature or requestNew feature or requestquestionFurther information is requestedFurther information is requested
Description
Summary
Implement dynamic resolution rendering that adjusts render resolution based on frame time budget. During fast camera movement or at extreme render distances, render at lower resolution and upscale via TAA. This keeps frame time consistent regardless of scene complexity.
Depends on: #388 (double-buffer upload — needs stable frame pacing)
How It Works
- Each frame: measure GPU time of previous frame
- If over budget (e.g., 16ms for 60 FPS target): reduce resolution scale (e.g., 0.7x)
- If under budget: increase resolution scale (e.g., 1.0x = native)
- Render at adjusted resolution into offscreen target
- TAA resolve + upscale to native swapchain resolution
- Smooth transitions: scale changes ±0.01 per frame (no popping)
Implementation Plan
Step 1: Offscreen render targets
- Create color + depth attachments at dynamically-sized resolution
- When scale changes: recreate these targets (or pre-allocate at max size and use view subsets)
- More efficient: pre-allocate at native resolution, use
vkCmdSetViewport/vkCmdSetScissorto render into a sub-region, then upscale
Step 2: Frame time tracking
- Use existing GPU timestamps from
rhi_timing.zig - Track rolling average over 8 frames to avoid thrashing
- Budget: configurable (16ms for 60 FPS, 8ms for 120 FPS)
Step 3: Scale adjustment logic
const target_ms = 1000.0 / target_fps;
const current_ms = rolling_avg_gpu_ms;
if (current_ms > target_ms * 1.1) {
// Over budget: reduce scale
scale = @max(scale - 0.02, min_scale);
} else if (current_ms < target_ms * 0.8) {
// Under budget: increase scale
scale = @min(scale + 0.01, max_scale);
}Step 4: TAA upscale integration
- TAA pass already exists (
taa_system.zig) - Modify to accept input at lower resolution and output at native
- TAA's temporal accumulation naturally smooths the upscale
- Jitter pattern scaled to match render resolution
Step 5: Settings integration
- Add "Dynamic Resolution" toggle to settings
- Add min/max scale bounds (default: 0.5x - 1.0x)
- Add target FPS setting (60, 120, 144, unlimited)
- Show current scale in timing overlay
Step 6: Quality considerations
- UI always renders at native resolution (no blur on text/menus)
- Only world rendering uses dynamic resolution
- Post-processing (bloom, FXAA) runs at native resolution on upscaled image
Files to Modify
src/engine/graphics/vulkan/frame_manager.zig— dynamic render targetssrc/engine/graphics/vulkan/swapchain_presenter.zig— resolve to nativesrc/engine/graphics/vulkan/taa_system.zig— accept variable input resolutionsrc/engine/graphics/render_graph.zig— pass resolution to sub-passessrc/engine/ui/timing_overlay.zig— show current scalesrc/game/settings/data.zig— dynamic resolution toggle, min/max scale, target FPS
Testing
- Resolution scale adjusts smoothly under heavy load
- No visible popping when scale changes
- UI remains sharp at all scales
- TAA quality maintained at non-native resolution
- Frame time stays within budget at 256+ chunks with dynamic resolution
- Disabling toggle locks to native resolution
- Extreme preset (512 chunks) remains playable
Roadmap: docs/PERFORMANCE_ROADMAP.md — Batch 6, Issue 4B
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
batch-6Batch 6: CapstoneBatch 6: CapstonedocumentationImprovements or additions to documentationImprovements or additions to documentationengineenhancementNew feature or requestNew feature or requestquestionFurther information is requestedFurther information is requested