Skip to content

About

Temporal Variance Shadow Optimizer for Unity URP — adaptive runtime cascade tuning powered by shadow-atlas variance. Now with extra Tasty.

Topics

Resources

Stars

26 stars

Watchers

2 watching

Forks

Repository files navigation

TVSO — Temporal Variance Shadow Optimizer for Unity URP

Dynamic, runtime-aware shadow cascade optimisation for Unity URP.
v0.2.2 — now with extra Tasty.

TVSO samples the URP main-light shadow atlas, estimates temporal/shadow variance across the cascade quadrants, and safely adjusts 4-cascade split behaviour at runtime. The aim is simple: spend shadow detail where the scene is visually active, back off when it is not, and avoid manually babysitting cascade splits for every test scene.

It is not a magic FPS button. It is a smarter shadow-cascade helper for scenes where static shadow settings are leaving performance or stability on the table.

Why TVSO exists

URP shadow cascades are usually configured as static project/render-pipeline settings. That is fine for simple scenes, but awkward for projects where the camera moves through dense, uneven, or wildly different environments.

TVSO adds an adaptive runtime layer:

  • Detects variance in the active URP shadow atlas using a lightweight compute shader.
  • Classifies cascade activity into low/mid/high pressure states.
  • Applies safer cascade split changes only after stable variance changes.
  • Restores original cascade splits on disable so test sessions do not permanently contaminate project settings.
  • Supports ObserveOnly mode so you can gather variance data without touching render settings.
  • Provides profiles and presets for Safe, Balanced, Aggressive, Manual, and Off workflows.

Same shadows, smarter serving suggestion — now with extra Tasty.

Headline features

  • GPU-powered shadow variance sampling.
  • AsyncGPUReadback pipeline with shutdown safety guards.
  • Dynamic URP cascade split adjustment for 4-cascade 2x2 shadow atlases.
  • Safe / Balanced / Aggressive presets.
  • TVSOProfile ScriptableObject workflow.
  • Off / ObserveOnly / Safe / Balanced / Aggressive / Manual modes.
  • Original cascade capture and restore-on-disable.
  • Split clamps, minimum split gap enforcement, and redundant-write avoidance.
  • Variance smoothing, promote/demote frame requirements, and retune cooldown.
  • Dynamic dispatch cadence that can back off when full-rate checks are not needed.
  • Runtime debug panel, inspector helpers, and CSV session logging.
  • Public API hooks for gameplay systems, photo mode, fast movement, and temporary profiles.
  • Benchmark helper scripts for repeatable Unity scene tests.

What changed in v0.2.2

v0.2.2 focuses on runtime safety, cleaner benchmarking, and URP correctness:

  • Dynamic dispatch no longer runs faster than the configured base cadence.
  • Readbacks now obey a hard safety floor to reduce driver/editor pressure.
  • ObserveOnly defaults to a cheaper minimum dispatch interval.
  • Removed a per-readback managed allocation.
  • CSV logging is buffered instead of opening/flushing every row.
  • Runtime panels and unused cascade keywords default off.
  • TVSO-owned global cascade keywords are cleaned up between phases.
  • Split writes are skipped when they would not meaningfully change active values.
  • URP 14 active cascade4Split is targeted directly, with Built-in Render Pipeline fallback retained.
  • Benchmark helpers now report active URP cascade split values more accurately.

Early benchmark results

These are early real-world/editor tests, not a universal guarantee. The useful pattern is that TVSO behaves politely in a clean official URP scene, then shows more benefit in a chaotic heavy scene where adaptive shadows are actually needed.

Each phase below used three 60-second repeats.

Official Unity URP Oasis directional-light test

Phase Avg FPS 1% Low FPS Avg frame ms P95 frame ms Readback errors Split applications
Baseline Off 183.92 138.63 5.45 6.59 0 0
ObserveOnly 183.59 136.39 5.45 6.62 0 0
Safe 186.07 141.28 5.37 6.53 0 18 avg
Balanced 186.51 137.99 5.36 6.53 0 24 avg

Takeaway: in a clean official URP scene, TVSO stayed close to baseline. Safe/Balanced produced small average-FPS improvements, while ObserveOnly remained effectively neutral and recorded no readback errors.

Hover City stress scene

Phase Avg FPS 1% Low FPS 0.1% Low FPS Avg frame ms P95 frame ms P99 frame ms Readback errors
Baseline Off 23.71 2.49 0.84 75.62 309.58 407.64 0
ObserveOnly 23.64 2.75 1.36 43.04 180.47 368.77 0
Safe 25.94 7.39 2.84 39.52 103.29 135.61 0
Balanced 26.86 7.58 2.89 38.92 104.90 132.05 0

Compared with Baseline Off in the Hover City stress scene:

  • Safe: +9.4% average FPS, +196% 1% low FPS, -66.6% P95 frame time, -66.7% P99 frame time.
  • Balanced: +13.3% average FPS, +204% 1% low FPS, -66.1% P95 frame time, -67.6% P99 frame time.
  • Readback errors: 0 across all captured benchmark phases.

Takeaway: the heaviest scene is where TVSO looks most useful. The best result here is not just the average FPS bump; it is the much smoother recovery from ugly frame-time spikes.

Raw CSV files and a generated analysis summary are included in Benchmarks/.

Installation

  1. Copy Assets/54DN/TVSO into your Unity project's Assets folder.
  2. Make sure your project uses URP with main-light shadows and 4 cascades enabled.
  3. Add TemporalVarianceShadowOptimizerURP to your main gameplay camera.
  4. Assign VarianceComputeURP_Atlas.compute to the component's Variance Compute field.
  5. Start with Mode = ObserveOnly and keep Show Runtime Panel enabled only while testing.
  6. Enter Play Mode and confirm variance/readback values update.
  7. Switch to Safe or Balanced once ObserveOnly is confirmed.
  8. Stop Play Mode and confirm your original cascade splits are restored.

Optional benchmark tools are in Assets/54DN/TVSO_Benchmark_Addons.

Recommended first test

  1. Open a representative scene.
  2. Set TVSO to ObserveOnly.
  3. Enable CSV logging for a 30-60 second run.
  4. Switch to Safe and repeat the same camera path.
  5. Switch to Balanced and repeat.
  6. Compare average FPS, frame-time percentiles, readback errors, and split applications.

For stable public screenshots or store pages, prefer the Safe or Balanced results. Treat Aggressive as a tuning mode for hard stress tests, not the default sales pitch.

Profiles

Create a profile from:

Create > 54DN > TVSO > Profile

Then assign it to the TVSO component and leave Use Profile Settings enabled. Profiles are useful when you want scene-specific behaviour without rewriting camera setup.

Public API examples

TemporalVarianceShadowOptimizerURP tvso = FindObjectOfType<TemporalVarianceShadowOptimizerURP>();

// Pause TVSO during photo mode, menus, or controlled capture.
tvso.Suspend("Photo Mode");
tvso.Resume();

// Let your movement/camera system tell TVSO that the scene is moving quickly.
tvso.SetExternalMotionIntensity(1.0f);

// Temporarily push a cinematic or aggressive profile.
tvso.PushTemporaryProfile(myProfile, 10f);

Current limitations

  • URP-focused release.
  • Tested against Unity 2022 / URP 14 style projects.
  • Assumes URP's main-light shadow atlas is available as _MainLightShadowmapTexture.
  • Designed around 4-cascade, 2x2 cascade atlas layouts.
  • Does not yet tune shadow bias or normal bias.
  • Does not yet include true realtime heatmap overlays.
  • HDRP and Built-in Render Pipeline backends are future work.

Roadmap

  • Threshold auto-tuning and stronger learning workflow.
  • Bias and normal-bias optimisation.
  • TVSO zones / volumes for area-specific behaviour.
  • Realtime debug heatmap overlay.
  • More formal benchmark suite and sample scenes.
  • HDRP support investigation.
  • Built-in Render Pipeline support investigation.
  • Unity 6 package split if needed.

Development note

TVSO has been quiet for a while because I have been deep in development on FROGUE, my Vulkan-based engine project. FROGUE takes one of TVSO's core ideas — wasted compute is a bug — and pushes it much further into a pulse-based runtime architecture with stronger debugging, reporting, and confidence-tracking systems.

That does not mean TVSO is abandoned. If anything, TVSO is one of the small systems that helped sharpen the design direction: observe runtime behaviour, detect waste, act only when useful, and make the engine explain what it is doing.

Internal FROGUE experiments are already exploring high-confidence runtime reporting and diagnostic feedback, including current test scenarios reaching 99.7% reporting confidence. More on that later. If you are interested. If not you just wasted your time reading this. Hah.

For now, TVSO remains a focused Unity URP tool: smarter shadows and safer cascade tuning.

Credits

Created by David Alex Cappleman.
Original system design and implementation by David Alex Cappleman.

License

MIT License. Use it, modify it, break it, improve it, and make your shadows tastier.

About

Temporal Variance Shadow Optimizer for Unity URP — adaptive runtime cascade tuning powered by shadow-atlas variance. Now with extra Tasty.

Topics

Resources

Stars

26 stars

Watchers

2 watching

Forks

Releases

Packages

Contributors

Languages