Help the user set up, configure, and debug post-processing effects using URP's Volume framework.
Goal: The user should have a working visual result with zero console errors after setup.
0. Prerequisite: an Editor you can run C# in
Volume profiles, VolumeParameter.overrideState, and the camera's post-processing flags are
Editor/runtime object state — the checks and edits below all run C# inside a live Editor.
The unity-cli skill owns getting you there — installing the CLI, confirming a connected
Editor, adding the project's com.unity.pipeline package, telling a genuinely absent Editor
apart from one stuck in Safe Mode, and discovering the Editor's command catalog. Follow it
first; don't re-derive any of it here. You need eval in particular, not just a reachable
Editor: its presence depends on the Pipeline package version, not on the CLI. If it's
missing, say so and stop.
Run C# through the connected Editor with the eval command. Discover its parameter shape
from unity command --format json rather than assuming one — the inline form is
unity command eval --caller plugin --skill urp-postprocessing --code '<snippet>', and some Pipeline versions also register
eval_file for running a snippet from a file. Check the catalog before reaching for
eval_file; it is frequently absent. unity command defaults to a 30 second timeout.
Passing C# to eval
eval compiles a statement block, not a file. Two consequences, both of which cause a
compile error rather than a warning:
- No
usingdirectives. The compiler readsusing UnityEngine;as a resource-disposal statement and rejects it (CS0210). - Types must be fully qualified. A bare
AssetDatabaseorVolumedoes not resolve (CS0246/CS0103), and a bareObjectis ambiguous withobject(CS0104).
Where a snippet below is written as a file — with usings, for readability, or because it is
meant to be saved into the project — qualify the types before passing it to eval.
0. Pre-Flight Checks
Before configuring any effect, verify all checks. Fix failures first.
- URP is the active render pipeline — If not, inform the user and stop.
- HDR is enabled on the URP Asset — Required for Tonemapping. Bloom works best with HDR; in SDR it still works but
thresholdmust be < 1. - Camera has post-processing enabled —
renderPostProcessingmust betrue(defaults tofalse). Camera Stacking: only aCameraRenderType.Basecamera (or the lastOverlayin the stack) should enable post-processing. Also verify the Renderer's PostProcessData asset is not null — if it is, the post-process pass won't exist. - The Volume's GameObject layer is in the Camera's Volume Layer Mask —
volumeLayerMaskdefaults to layer 0 "Default" only. The Volume'sGameObject.layermust be included, otherwise the camera ignores it. - Volume exists with
enabled = true, a valid Profile, and at least one override — TheVolumecomponent must be enabled, have a non-nullprofile(orsharedProfile), and at least oneVolumeComponentwithoverrideState = trueon its properties.
Pre-Flight Check Snippet
Run this to verify the setup programmatically:
1. Volume Setup
Effects are added as VolumeComponent overrides on a VolumeProfile (a ScriptableObject).
Global Volume (most common): GameObject with Volume component, isGlobal = true, profile assigned. Affects every camera whose volumeLayerMask includes the Volume's layer.
Local Volume (optional, but takes precedence): GameObject with trigger Collider + Volume component, isGlobal = false. Properties:
priority(float) — higher values override lower when volumes overlap.blendDistance(float) — outer distance in world units to start blending from (0 = no blend, instant transition at collider boundary).weight(float, 0–1) — scales the volume's overall influence.
2. Post-Processing Effects
All effects are VolumeComponent subclasses added as overrides on a VolumeProfile via profile.Add<T>(). Check existence with profile.Has<T>() or profile.TryGet<T>(out var t). Remove with profile.Remove<T>().
Every property is a VolumeParameter. You must set overrideState = true before setting value, otherwise the Volume system ignores it.
When configuring a specific effect, load the full API reference:
- references/effect-reference.md [blocked] — All VolumeComponent properties by effect (Bloom, Tonemapping, ColorAdjustments, DepthOfField, Vignette, MotionBlur, FilmGrain, ChromaticAberration, SplitToning, LensDistortion, WhiteBalance, PaniniProjection, LiftGammaGain, ShadowsMidtonesHighlights, ColorCurves, ChannelMixer)
For code templates:
- references/code-templates.md [blocked] — Global Volume setup, camera post-processing, and profile modification templates
3. Anti-Hallucination Rules
Required Usings
These apply when you write a .cs file into the project. A snippet passed to eval cannot
carry them — qualify the types instead (see "Passing C# to eval" above).
Wrong → Correct API Mapping
Key Facts
overrideState = trueis required on everyVolumeParameteryou set. The volume system skips parameters whereoverrideStateisfalse. This is the #1 scripting mistake.sharedProfile= returns the asset directly (edits persist to disk).profile= auto-clones into an instance if needed (safe for runtime edits). Check withvolume.HasInstantiatedProfile().profile.Add<T>(bool overrides = false)— passtrueto auto-enableoverrideStateon all parameters of the added component.
4. Debugging Checklist
When post-processing isn't working, check in order:
cam.TryGetComponent<UniversalAdditionalCameraData>(out var data)succeeds anddata.renderPostProcessingistrue?- Volume exists in scene with a non-null
profile(orsharedProfile) assigned? - Overrides added via
profile.Add<T>()ANDoverrideState = trueon each property you set? - Volume's
GameObject.layeris included in camera'sdata.volumeLayerMask? (Default mask is layer 0 "Default" only.) volume.isGlobal = true(for global), or camera is inside the Volume's triggerCollider(for local)?- Camera
data.renderTypeisCameraRenderType.Base, notOverlay? (Overlay cameras composite onto the Base camera's output.) UniversalRenderPipeline.asset.supportsHDRistrue? Required for Bloom and Tonemapping.- Viewing in Game view? Scene view has a separate post-processing toggle in its toolbar.
5. Common Recipes
Format: Effect property=value. Bloom values are threshold/intensity/scatter.
Cinematic (Film): Tonemapping mode=ACES, ColorAdjustments contrast=15 saturation=-10, Bloom threshold=0.9 intensity=0.5 scatter=0.7, Vignette intensity=0.3 smoothness=0.4, FilmGrain type=Medium1 intensity=0.2
Stylized/Vibrant: Tonemapping mode=Neutral, ColorAdjustments saturation=20 contrast=10, Bloom threshold=0.8 intensity=1.5 scatter=0.6, SplitToning highlights=warm shadows=cool
Horror/Dark: ColorAdjustments postExposure=-0.5 saturation=-30 contrast=20, Vignette intensity=0.5 smoothness=0.3 color=dark-red, FilmGrain type=Large01 intensity=0.4, ChromaticAberration intensity=0.15
Clean/Mobile: Tonemapping mode=Neutral, ColorAdjustments postExposure=0.2, Bloom threshold=1.0 intensity=0.3 (subtle). Avoid FilmGrain, MotionBlur, DepthOfField on mobile.
6. Final Confirmation
After setup, report to user:


