# 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.*
