# Planar Capture System Architecture — UE5 Modular Game Framework **Version:** 1.0 | **Systems:** 136-147 (12 systems) | **Phase:** 17 — Rendering & Visual This document specifies the architecture of the Planar Capture System — a unified rendering pipeline for mirrors, portals, monitors, and horror surfaces. One capture pipeline, one quality manager, one material interface. --- ## Architecture Overview ``` ┌─────────────────────────────────────────────────────────────────────────────┐ │ BLUEPRINT LAYER (Designer-Facing) │ │ BP_Mirror BP_HorrorMirror BP_Portal BP_Monitor BP_FakeWindow │ │ DA_PlanarCaptureProfile MPC_CaptureSurface MI_Mirror_Clean/Dirty/Steam │ ├─────────────────────────────────────────────────────────────────────────────┤ │ C++ LAYER (Performance-Critical) │ │ UBPC_PlanarCapture — SceneCapture2D lifecycle, camera math │ │ ABP_PlanarCaptureActor — Surface mesh, MDI, overlap/proximity │ │ USS_PlanarCaptureManager — Global budget, RT pool, scoring (WorldSubsystem + FTickable) │ │ UPlanarCaptureCameraUtils — Mirror/Portal/Oblique math (static) │ ├─────────────────────────────────────────────────────────────────────────────┤ │ UE5 ENGINE │ │ USceneCaptureComponent2D UTextureRenderTarget2D UMaterialParameterColl │ └─────────────────────────────────────────────────────────────────────────────┘ ``` --- ## System Map (12 Systems — Files 136-147) | # | System | Type | Parent Class | Purpose | |---|--------|------|-------------|---------| | 136 | `BPC_PlanarCapture` | BPC_ Component | `ActorComponent` | Core capture: SceneCapture2D lifecycle, camera math, RT management, actor lists, horror ring buffer | | 137 | `BP_PlanarCaptureActor` | BP_ Actor | `Actor` | Placeable surface actor: mesh, MDI, proximity trigger, manager registration | | 138 | `SS_PlanarCaptureManager` | SS_ Subsystem | `WorldSubsystem` | Global budget manager: surface scoring, quality tier assignment, RT pool | | 139 | `BP_Mirror` | BP_ Actor | `BP_PlanarCaptureActor` | Standard mirror: Mode=Mirror, dirt/steam/condensation layers, aging | | 140 | `BP_Portal` | BP_ Actor | `BP_PlanarCaptureActor` | Portal surface: Mode=Portal, linked target, teleport on overlap, clip plane | | 141 | `BP_Monitor` | BP_ Actor | `BP_PlanarCaptureActor` | Security screen/TV: Mode=Monitor, fixed camera ref, low update rate, scanlines | | 142 | `BP_HorrorMirror` | BP_ Actor | `BP_Mirror` | Horror mirror: wrong reflection actor, delayed frame, steam text reveal, scare events | | 143 | `BP_FakeWindow` | BP_ Actor | `BP_PlanarCaptureActor` | Architectural fake window: Mode=FakeWindow, linked sublevel, weather overlay | | 144 | `M_CaptureSurface_Master` | Material | `Material` | Master unlit material: RT sample, condensation, dirt, steam, horror layers | | 145 | `MPC_CaptureSurface` | MPC | `MaterialParameterCollection` | Global MPC: SteamIntensity, DirtOpacity, MirrorDarkness, WrongReflectionBlend, etc. (10 params) | | 146 | `DA_PlanarCaptureProfile` | DA_ Data Asset | `PrimaryDataAsset` | Per-surface capture config: default mode, quality profile overrides, actor lists | | 147 | `MI_Mirror_Clean/Dirty/Steam/Horror` | MI_ Instances | `M_CaptureSurface_Master` | Pre-configured material instances for common mirror states | --- ## Enums ### `EPlanarCaptureMode` (C++: defined in `PlanarCaptureCommon.h`) | Value | Description | |-------|-------------| | `Mirror` | Standard planar mirror reflection | | `Portal` | Portal with linked target surface | | `Monitor` | Fixed-camera security screen / TV | | `HorrorMirror` | Mirror with horror features (wrong reflection, delayed frame) | | `HorrorPortal` | Portal with horror features | | `FakeWindow` | Architectural fake window (parallax, weather) | ### `EPlanarCaptureQualityTier` (C++: defined in `PlanarCaptureCommon.h`) | Value | RT Size | FPS | Shadows | Lumen | Post | Clip Plane | |-------|---------|-----|---------|-------|------|-----------| | `Off` | — | 0 | — | — | — | — | | `Low` | 256 | 4 | No | No | No | No | | `Medium` | 512 | 15 | Dynamic | Optional | No | Yes | | `High` | 1024 | 30 | Full | Yes | Minimal | Yes | | `Hero` | 2048 | 60 | Full | Yes | Full | Yes | --- ## Communication Matrix | Source | Target | Method | What | |--------|--------|--------|------| | `BP_PlanarCaptureActor` | `SS_PlanarCaptureManager` | Direct (RegisterSurface) | Registers on BeginPlay | | `SS_PlanarCaptureManager` | `BPC_PlanarCapture` | Direct (ApplyQualityTier) | Assigns quality tier | | `BPC_PlanarCapture` | `USceneCaptureComponent2D` | Direct (owns) | Camera math + CaptureScene | | `BPC_PlanarCapture` | `MPC_CaptureSurface` | Direct (SetScalarParameter) | Pushes steam/dirt/horror params | | `BP_HorrorMirror` | `BPC_ScareEventSystem` (101) | Interface / Dispatcher | Triggers coordinated scares | | `BP_HorrorMirror` | `SS_AudioManager` (132) | Direct | Plays mirror horror SFX | | `BPC_PlanarCapture` | `BPC_StateManager` (130) | IsActionPermitted() | Checks if capture can activate | | `BP_Portal` | Player Pawn | Overlap Event | Teleports player through portal | --- ## Quality Scoring Algorithm ``` CompositeScore = (ScreenCoverage × 0.5) + (FacingAngle × 0.3) + (DistanceFactor × 0.1) + (ScriptedPriority × 0.1) Tier assignment: Score ≥ 0.8 → Hero (capped at GlobalQualityCap, max MaxHeroSurfaces) Score ≥ 0.5 → High (capped at max MaxHighSurfaces) Score ≥ 0.2 → Medium (capped at max MaxMediumSurfaces) Score > 0 → Low Score = 0 or !inFrustum → Off ``` --- ## Material Layer Stack (M_CaptureSurface_Master) ``` Layer 0: Render target sample (UV-flipped for mirror, straight for portal/monitor) Layer 1: Condensation normal map → distorts UV of RT sample Layer 2: Fresnel edge fade mask Layer 3: Dirt/scratch multiply (DirtOpacity MPC param) Layer 4: Steam/fog lerp (animated noise, SteamIntensity MPC param) Layer 5: Steam emissive glow (backlit fog, SteamEmissiveIntensity) Layer 6: Text reveal mask lerp (TextRevealProgress, uses steam as carrier) Layer 7: Mirror darkness multiply (MirrorDarkness MPC param) Layer 8: Wrong reflection crossfade (WrongReflectionBlend MPC param) Output: Unlit shading model ``` --- ## Horror Features | Feature | Driven By | Layer | |---------|-----------|-------| | Mirror-only ghost actor | ShowOnly list in C++ | C++ | | Wrong reflection Metahuman swap | ActivateHorrorReflection() | C++ | | Delayed frame reflection | FrameRingBuffer + DelayedReflectionBlend MPC | C++ + Material | | Steam fogging | SteamIntensity MPC → Layer 4 | Material | | Dirt / scratches | DirtOpacity MPC → Layer 3 | Material | | Condensation rivulets | CondensationFlow MPC → Layer 1 | Material | | UV distortion / breathing | DistortionAmplitude MPC → Layer 1 | Material | | Text in steam reveal | TextRevealProgress MPC → Layer 6 | Material | | Mirror goes dark | MirrorDarkness MPC → Layer 7 | Material | | Wrong reflection crossfade | WrongReflectionBlend MPC → Layer 8 | Material | | Surface aging/oxidation | SurfaceAge MPC → Layer 3 (tint) | Material | --- ## Blueprint Limitations & Workarounds ### `USceneCaptureComponent2D::CaptureScene()` (C++ Only) **Workaround:** Call from C++ in `UBPC_PlanarCapture`. Blueprint calls `CaptureNow()` which invokes C++ capture. **Affected Files:** 136, 139-143 ### `FSceneView::ViewMatrices` for Oblique Projection (C++ Only) **Workaround:** Use `UPlanarCaptureCameraUtils::ComputeObliqueProjectionMatrix()` (BlueprintCallable). **Affected Files:** 136, 140 ### `USceneCaptureComponent2D::ShowOnlyActors` Runtime Modification (Partial C++) **Workaround:** `UBPC_PlanarCapture::UpdateActorLists()` resolves TSoftObjectPtrs into the array. **Affected Files:** 136, 142 --- ## Performance Budget Guidelines | Tier | Max Simultaneous | RT Memory per Surface | GPU Cost | |------|-----------------|----------------------|----------| | Hero | 1 | 16 MB (2048² × 4B) | Very High | | High | 3 | 4 MB (1024² × 4B) | High | | Medium | 6 | 1 MB (512² × 4B) | Medium | | Low | Unlimited | 256 KB (256² × 4B) | Low | | Off | — | 0 | None | **Total Budget:** 128 MB default (configurable via `SS_PlanarCaptureManager.MaxTotalRenderTargetMemoryMB`) --- ## Multiplayer Considerations - Capture rendering is **local-only** — each client renders their own view - `BP_PlanarCaptureActor` replicates `bIsActive` for server-authoritative surface control - Horror events (wrong reflection activation) are triggered server-side and replicated via gameplay tags - No client prediction needed — captures are cosmetic --- ## Integration Points with Existing Systems | Existing System | Integration | |----------------|-------------| | `BPC_StateManager` (130) | Query `IsActionPermitted()` before enabling capture, teleport gating | | `BPC_ScareEventSystem` (101) | Horror mirror events trigger coordinated scares | | `SS_AudioManager` (132) | Mirror/portal SFX route through audio subsystem | | `SS_EnhancedInputManager` (128) | Input context switch for portal inspection mode | | `BPC_DiegeticDisplay` (18) | Monitors can display diegetic UI render targets | | `BPC_CameraStateLayer` (14) | Camera FOV adjustments during portal transitions | | `I_Persistable` (36) | Mirror surface state (destroyed, dirty, oxidized) saves/loads | | `DA_ScareEvent` (127) | Mirror apparition scare event data asset | | `WBP_SettingsMenu` (57) | Capture surface quality settings (Performance section) | --- ## Build Order (Phase 17) 1. **Phase 17a:** C++ Core — `PlanarCaptureCommon.h`, `PlanarCaptureCameraUtils`, `BPC_PlanarCapture`, `SS_PlanarCaptureManager`, `BP_PlanarCaptureActor` 2. **Phase 17b:** Material Foundation — `M_CaptureSurface_Master`, `MPC_CaptureSurface`, `MI_Mirror_*` instances 3. **Phase 17c:** Blueprint Actors — `BP_Mirror`, `BP_Portal`, `BP_Monitor`, `BP_HorrorMirror`, `BP_FakeWindow` 4. **Phase 17d:** Data Assets — `DA_PlanarCaptureProfile` 5. **Phase 17e:** Integration — Wire horror events to `BPC_ScareEventSystem`, audio to `SS_AudioManager`, persistence to `I_Persistable` --- *Planar Capture System Architecture v1.0 — See `docs/blueprints/17-capture/` for per-system blueprint specs.*