Skip to content

Multi-Camera System Implementation and Performance Optimizations#103

Merged
CubeBerry merged 5 commits into
mainfrom
Optimization
May 19, 2026
Merged

Multi-Camera System Implementation and Performance Optimizations#103
CubeBerry merged 5 commits into
mainfrom
Optimization

Conversation

@doyoung413

Copy link
Copy Markdown
Collaborator

Job System & Multithreaded Updates

  • Integrated a custom Job System to parallelize logic updates, particle simulations, and sprite management.
  • Optimized skeletal animation processing by offloading vertex transformations to worker threads.
  • Implemented the InputSnapshot pattern to ensure thread-safe input handling during concurrent updates.

Physics & Memory Optimization

  • Integrated Dynamic BVH for efficient broad-phase collision detection.
  • Improved GJK/EPA algorithm stability and optimized memory management for collision pairs.

Multi-Camera System Implementation

  • Added support for multiple camera rendering within a single frame.
  • Refined the rendering pipeline to handle independent viewports and projection matrices effectively.

NOTE

  • While the Multi-Camera system is functional, further optimization work is required to reduce redundant draw calls and improve GPU throughput when multiple cameras are active simultaneously.

Task-Based Job System Integration
- Replaced the existing ThreadManager with a JobSystem to manage CPU-bound tasks through a worker thread pool.
- Added JobSystem APIs (QueueWork, QueueParallelWork, WaitForWork, WaitForAll) using a counter-based synchronization method for thread management.

Thread-Safe Input Handling (InputSnapshot Pattern)
- Added an InputSnapshot structure that captures a read-only copy of the keyboard and mouse state at the start of each frame.
- Updated all game scripts and logic to read from InputSnapshot instead of InputManager to prevent race conditions when reading inputs during multithreaded updates.

Engine Loop Parallelization
- Modified GameStateManager::UpdateGameLogic to run ObjectManager, ParticleManager, and SpriteManager updates concurrently as independent jobs.
- Applied task dependencies to ensure PhysicsManager updates run only after ObjectManager jobs are completed, avoiding data races between object state changes and physics simulations.
- Replaced sequential iterations in internal systems with QueueParallelWork. Object states and 2D/3D physics integrations are now processed in batches across multiple threads.
Memory & Performance Optimization
- Eliminated heap allocation overhead in high-frequency collision loops by adopting thread_local static vectors for temporary calculation buffers.
- Replaced expensive pass-by-value parameter passing with const references across all physics mathematical functions to prevent unnecessary memory copying.

Broad Phase Spatial Partitioning (Dynamic BVH)
- Implemented a custom Dynamic Bounding Volume Hierarchy (BVH) tree using object pooling to efficiently manage 2D and 3D spatial data without dynamic allocations.
- Applied Fat AABBs and incremental tree updates using the Surface Area Heuristic (SAH) for 3D and Perimeter Heuristic for 2D, drastically reducing $O(N^2)$ broad-phase bottlenecks down to $O(N \log N)$.

Continuous Collision Detection (CCD) Pipeline Upgrade
- Optimized the FindClosestCollision CCD loop by querying the newly implemented BVH tree with swept AABBs, eliminating the massive overhead of iterating through all objects in the scene.

Narrow Phase Collision Revamp (GJK/EPA Integration)
- Replaced the legacy Separating Axis Theorem (SAT) logic with the Gilbert-Johnson-Keerthi (GJK) algorithm for discrete intersection testing, utilizing the Expanding Polytope Algorithm (EPA) for precise penetration depth, normal, and contact point extraction using barycentric coordinates.
- Introduced a unified GjkShape proxy structure to handle multiple collider types (Box, Sphere) seamlessly within a single collision pipeline, eliminating the need for virtual function overhead during geometry queries.
- Transitioned Continuous Collision Detection (CCD) from SAT-based directional sweeps to a unified SweptGJK routine, applying sub-stepping and binary search techniques to determine accurate Time of Impact (TOI) and prevent tunneling.

Physics Solver Stability & Sleep State Optimization
- Addressed micro-bouncing and jittering during resting contacts by introducing a velocity threshold in the linear impulse solver (CalculateLinearVelocity), neutralizing restitution for low-velocity impacts.
- Refined the wake-up trigger logic during position resolution to prevent rigid bodies from unnecessarily transitioning out of the sleep state upon insignificant micro-collisions.

Geometry Translation & Legacy Cleanup
- Fixed a broad-phase bug in ComputeAABB where rotational transformations of bounding vertices were ignored, ensuring accurately fitted bounding boxes for rotating polygons.
- Removed deprecated SAT helper functions, axis projection loops, and cached separating axis variables to streamline the Physics3D class architecture.
Skeletal Animation Multithreading (Job System Integration)
- Migrated skeletal animation bone transform calculations to the background using the Job System for parallel processing.
- Separated heavy CPU-bound matrix calculations from GPU memory uploads to optimize the main thread's frame time.

Render Infrastructure Enhancements (Command Queue Pattern)
- Implemented QueueGPUCommand: Introduced a thread-safe mechanism to queue GPU-related tasks (e.g., OpenGL buffer updates) from worker threads, preventing API context affinity issues.
- Implemented ProcessGPUCommands: Added a synchronization point on the main thread to flush and execute deferred GPU commands, ensuring stability in thread-dependent rendering APIs.

Normal Vector Visualization Pipeline Fix (GL/VK/DX)
- Fixed an issue where debug normal vectors on animated meshes remained frozen in T-pose by passing bone IDs and weights into the debug rendering pipeline.
- Updated the Normal3D shader to perform skeletal skinning computations identical to the main 3D shader, ensuring normal lines accurately follow the animated geometry.
- Resolved a Vulkan-specific bug where the vertex uniform dynamic offset was overwritten by the fragment offset, causing incorrect bone matrices to be bound and distorting specific joints.
- Fixed a DirectX 12 state creation error by explicitly mapping the BLENDINDICES and BLENDWEIGHTS attributes to the debug normal pipeline layout.
Multi-Camera Rendering System
- Modified CameraManager to manage the lifecycle, activation states, and rendering priority (layering) of multiple cameras.
- Implemented synchronized Viewport and Scissor Rectangle synchronization across DX12 (Forward, Deferred, Lighting, Skybox), OpenGL, and Vulkan backends.
- Resolved a critical deferred rendering artifact where sub-viewport rendering caused G-Buffer UV misalignment; fixed by decoupling Viewport (Full Render Resolution) and Scissor Rect (Camera Sub-region) in lighting passes to align sampling coordinates.
- Standardized cross-backend coordinate systems, specifically addressing Y-axis inversion between OpenGL and DX/VK to ensure uniform camera behavior across all APIs.
- Integrated an ImGui-based visual debug system that renders 3D camera frustums, orientations (Pitch/Yaw), and field-of-view in real-time.
- Optimized debug visualization (Physics colliders and skeletons) to support screen-space occlusion, ensuring debug lines are correctly clipped by overlapping camera viewports.
- Ensured full compatibility with FidelityFX (FSR) by dynamically scaling sub-viewports based on the ratio between internal render and display resolutions.
Renamed Camera Projections
- Transitioned the camera system terminology from "2D/3D" to "Orthographic/Perspective". This clarifies that a camera's projection method is an independent property from the scene's spatial dimension (2D or 3D).

DirectX 12 Multi-Camera Rendering Fix
- Resolved a critical DX12 issue where multiple cameras shared the same m_frameIndex offset, causing view/projection data corruption. Implemented WaitForGPU() synchronization and command list flushing per camera loop for strict context isolation.
- Removed redundant resource transition barriers during command list resets within camera loops, replacing them with simple OMSetRenderTargets rebinds to prevent validation errors.

Debug Rendering Infrastructure Enhancements
- Added RenderManager::DrawClippedLine to handle debug line rendering across multiple viewports. This function was introduced to support Picture-in-Picture (PiP) and complex multi-camera layouts. It mathematically clips debug line segments against overlapping camera boundaries, preventing debug graphics (like frustums or bone lines) from "bleeding" into other cameras' viewports and ensuring visual clarity for each independent view.

Camera Management & Debug Utilities
- Refactored DeleteCamera to correctly shift indices when preceding cameras are removed, and fixed a double-decrement bug in the ImGui interface.
- Added a "Show Camera Debug" checkbox to the Camera Manager's ImGui panel to easily toggle frustum and position indicators.
- Updated the CameraController to allow adding any camera type regardless of the current demo's dimension. The control logic now dynamically adapts based on the camera's projection type rather than the scene type: Orthographic cameras utilize 2D-style pan/zoom, while Perspective cameras utilize 3D-style WASD movement and mouse rotation, regardless of the environment.

Debug Rendering Clipping Optimizations
- Commented out aggressive Z-clipping and strict off-screen discard conditions in DrawClippedLine to ensure debug lines remain visible even when vertices extend outside the visible viewport.

2D Physics Stability and Tunneling Fixes
- Implemented velocity-aware collision normal selection in the SAT resolution logic for Physics2D. This prevents fast-moving objects from being ejected to the wrong side of a wall when they penetrate past its midpoint in a single frame, ensuring billiard balls always bounce back correctly even at maximum speeds.

Performance Consideration
- Future optimization for the multi-camera pipeline is required, as the current structure executes a full render loop per camera, leading to linear increases in CPU/GPU load as camera counts grow.
@doyoung413 doyoung413 self-assigned this May 4, 2026
@doyoung413 doyoung413 added enhancement New feature or request optimization Optimize code structure or performance labels May 4, 2026
@CubeBerry
CubeBerry self-requested a review May 4, 2026 06:35
@CubeBerry
CubeBerry merged commit 03b597a into main May 19, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request optimization Optimize code structure or performance

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants