urp-postprocessing
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseHelp 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.
帮助用户使用URP的Volume框架设置、配置和调试后期处理效果。
目标:设置完成后,用户应获得可正常运行的视觉效果,且控制台无任何错误。
0. Prerequisite: an Editor you can run C# in
0. 前提条件:可运行C#的编辑器
Volume profiles, , and the camera's post-processing flags are
Editor/runtime object state — the checks and edits below all run C# inside a live Editor.
VolumeParameter.overrideStateThe skill owns getting you there — installing the CLI, confirming a connected
Editor, adding the project's 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 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.
unity-clicom.unity.pipelineevalRun C# through the connected Editor with the command. Discover its parameter shape
from rather than assuming one — the inline form is
, and some Pipeline versions also register
for running a snippet from a file. Check the catalog before reaching for
; it is frequently absent. defaults to a 30 second timeout.
evalunity command --format jsonunity command eval --code '<snippet>'eval_fileeval_fileunity commandVolume配置文件、以及相机的后期处理标志均为编辑器/运行时对象状态——以下所有检查和编辑操作均在实时编辑器中运行C#代码。
VolumeParameter.overrideStateunity-clicom.unity.pipelineeval使用命令通过已连接的编辑器运行C#代码。请通过查看其参数格式,而非自行假设——内联形式为,部分Pipeline版本还注册了用于运行文件中的代码片段。在使用前请先检查命令目录;该功能经常不存在。默认超时时间为30秒。
evalunity command --format jsonunity command eval --code '<snippet>'eval_fileeval_fileunity commandPassing C# to eval
eval向eval
传递C#代码
evaleval- No directives. The compiler reads
usingas a resource-disposal statement and rejects it (using UnityEngine;).CS0210 - Types must be fully qualified. A bare or
AssetDatabasedoes not resolve (Volume/CS0246), and a bareCS0103is ambiguous withObject(object).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 .
evaleval- 不支持指令。编译器会将
using视为资源释放语句并拒绝执行(错误码using UnityEngine;)。CS0210 - 类型必须完全限定。未限定的或
AssetDatabase无法解析(错误码Volume/CS0246),未限定的CS0103会与Object产生歧义(错误码object)。CS0104
若下方的代码片段是以文件形式编写的——包含指令以提升可读性,或旨在保存到项目中——请在传递给前先对类型进行限定。
usingeval0. Pre-Flight Checks
0. 预检检查
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 must be < 1.
threshold - Camera has post-processing enabled — must be
renderPostProcessing(defaults totrue). Camera Stacking: only afalsecamera (or the lastCameraRenderType.Basein 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.Overlay - The Volume's GameObject layer is in the Camera's Volume Layer Mask — defaults to layer 0 "Default" only. The Volume's
volumeLayerMaskmust be included, otherwise the camera ignores it.GameObject.layer - Volume exists with , a valid Profile, and at least one override — The
enabled = truecomponent must be enabled, have a non-nullVolume(orprofile), and at least onesharedProfilewithVolumeComponenton its properties.overrideState = true
在配置任何效果之前,请完成所有检查。先修复检查不通过的项。
- URP为当前激活的渲染管线——若不是,请告知用户并停止操作。
- URP资源已启用HDR——这是色调映射的必要条件。Bloom在HDR下效果最佳;在SDR模式下仍可工作,但必须小于1。
threshold - 相机已启用后期处理——必须设为
renderPostProcessing(默认值为true)。相机堆叠:仅false相机(或堆叠中的最后一个CameraRenderType.Base相机)应启用后期处理。同时需验证渲染器的PostProcessData资源不为空——若为空,则后期处理通道不存在。Overlay - Volume的游戏对象层包含在相机的Volume层遮罩中——默认仅包含0层“Default”。Volume的
volumeLayerMask必须被包含在内,否则相机会忽略该Volume。GameObject.layer - 存在已启用的Volume,且带有有效的Profile及至少一个覆盖项——组件必须启用,拥有非空的
Volume(或profile),且至少有一个sharedProfile的属性设置了VolumeComponent。overrideState = true
Pre-Flight Check Snippet
预检检查代码片段
Run this to verify the setup programmatically:
csharp
// `eval` compiles a statement block, not a file: no `using` directives are
// allowed, so every type is fully qualified.
var report = new System.Text.StringBuilder();
// 1. Check URP is active — a hard stop, so throw: it fails the eval loudly
var urpAsset = UnityEngine.Rendering.Universal.UniversalRenderPipeline.asset;
if (urpAsset == null)
throw new System.Exception("URP is not the active render pipeline.");
// 2. Check HDR
if (!urpAsset.supportsHDR)
report.AppendLine("Warning: HDR is disabled on the URP Asset. Tonemapping won't work; Bloom requires threshold < 1.");
// 3. Check camera post-processing
var cam = UnityEngine.Camera.main;
if (cam == null)
throw new System.Exception("No Main Camera found.");
if (!cam.TryGetComponent<UnityEngine.Rendering.Universal.UniversalAdditionalCameraData>(out var camData))
throw new System.Exception("Missing UniversalAdditionalCameraData on camera. Is URP active?");
if (!camData.renderPostProcessing)
report.AppendLine("Warning: Post-processing is disabled on the camera. Enable via camData.renderPostProcessing = true.");
// 4. Check volume layer mask
var volumes = UnityEngine.Object.FindObjectsByType<UnityEngine.Rendering.Volume>(UnityEngine.FindObjectsSortMode.None);
foreach (var vol in volumes)
{
if (!vol.enabled) { report.AppendLine($"Warning: Volume '{vol.name}' is disabled."); continue; }
if ((camData.volumeLayerMask & (1 << vol.gameObject.layer)) == 0)
report.AppendLine($"Warning: Volume '{vol.name}' on layer {vol.gameObject.layer} is not in camera's volumeLayerMask.");
// 5. Check profile and overrides
var profile = vol.sharedProfile;
if (profile == null) { report.AppendLine($"Warning: Volume '{vol.name}' has no profile assigned."); continue; }
if (profile.components.Count == 0)
report.AppendLine($"Warning: Volume '{vol.name}' profile has no overrides.");
}
// Return the findings: logs land in the Editor console, the returned value comes back to you
return report.Length == 0 ? "Post-processing setup looks correct." : report.ToString();运行以下代码以程序化验证设置:
csharp
// `eval` compiles a statement block, not a file: no `using` directives are
// allowed, so every type is fully qualified.
var report = new System.Text.StringBuilder();
// 1. Check URP is active — a hard stop, so throw: it fails the eval loudly
var urpAsset = UnityEngine.Rendering.Universal.UniversalRenderPipeline.asset;
if (urpAsset == null)
throw new System.Exception("URP is not the active render pipeline.");
// 2. Check HDR
if (!urpAsset.supportsHDR)
report.AppendLine("Warning: HDR is disabled on the URP Asset. Tonemapping won't work; Bloom requires threshold < 1.");
// 3. Check camera post-processing
var cam = UnityEngine.Camera.main;
if (cam == null)
throw new System.Exception("No Main Camera found.");
if (!cam.TryGetComponent<UnityEngine.Rendering.Universal.UniversalAdditionalCameraData>(out var camData))
throw new System.Exception("Missing UniversalAdditionalCameraData on camera. Is URP active?");
if (!camData.renderPostProcessing)
report.AppendLine("Warning: Post-processing is disabled on the camera. Enable via camData.renderPostProcessing = true.");
// 4. Check volume layer mask
var volumes = UnityEngine.Object.FindObjectsByType<UnityEngine.Rendering.Volume>(UnityEngine.FindObjectsSortMode.None);
foreach (var vol in volumes)
{
if (!vol.enabled) { report.AppendLine($"Warning: Volume '{vol.name}' is disabled."); continue; }
if ((camData.volumeLayerMask & (1 << vol.gameObject.layer)) == 0)
report.AppendLine($"Warning: Volume '{vol.name}' on layer {vol.gameObject.layer} is not in camera's volumeLayerMask.");
// 5. Check profile and overrides
var profile = vol.sharedProfile;
if (profile == null) { report.AppendLine($"Warning: Volume '{vol.name}' has no profile assigned."); continue; }
if (profile.components.Count == 0)
report.AppendLine($"Warning: Volume '{vol.name}' profile has no overrides.");
}
// Return the findings: logs land in the Editor console, the returned value comes back to you
return report.Length == 0 ? "Post-processing setup looks correct." : report.ToString();1. Volume Setup
1. Volume设置
Effects are added as VolumeComponent overrides on a VolumeProfile (a ).
ScriptableObjectGlobal Volume (most common): GameObject with component, , assigned. Affects every camera whose includes the Volume's layer.
VolumeisGlobal = trueprofilevolumeLayerMaskLocal Volume (optional, but takes precedence): GameObject with trigger + component, . Properties:
ColliderVolumeisGlobal = false- (float) — higher values override lower when volumes overlap.
priority - (float) — outer distance in world units to start blending from (0 = no blend, instant transition at collider boundary).
blendDistance - (float, 0–1) — scales the volume's overall influence.
weight
效果以VolumeComponent覆盖项的形式添加到VolumeProfile(一种)中。
ScriptableObject全局Volume(最常用):带有组件的游戏对象,,已分配。影响所有包含该Volume所在层的相机。
VolumeisGlobal = trueprofilevolumeLayerMask局部Volume(可选,但优先级更高):带有碰撞触发器 + 组件的游戏对象,。属性:
ColliderVolumeisGlobal = false- (浮点数)——当多个Volume重叠时,值越高优先级越高。
priority - (浮点数)——开始混合的世界单位外距离(0表示无混合,在碰撞器边界处即时切换)。
blendDistance - (浮点数,0–1)——缩放Volume的整体影响程度。
weight
2. Post-Processing Effects
2. 后期处理效果
All effects are subclasses added as overrides on a via . Check existence with or . Remove with .
VolumeComponentVolumeProfileprofile.Add<T>()profile.Has<T>()profile.TryGet<T>(out var t)profile.Remove<T>()Every property is a . You must set before setting , otherwise the Volume system ignores it.
VolumeParameteroverrideState = truevalueWhen configuring a specific effect, load the full API reference:
- references/effect-reference.md — 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 — Global Volume setup, camera post-processing, and profile modification templates
所有效果均为的子类,通过作为覆盖项添加到中。使用或检查是否存在。使用移除。
VolumeComponentprofile.Add<T>()VolumeProfileprofile.Has<T>()profile.TryGet<T>(out var t)profile.Remove<T>()每个属性均为。在设置之前,必须设置,否则Volume系统会忽略该属性。
VolumeParametervalueoverrideState = true配置特定效果时,请查阅完整API参考:
- references/effect-reference.md — 按效果分类的所有VolumeComponent属性(Bloom、Tonemapping、ColorAdjustments、DepthOfField、Vignette、MotionBlur、FilmGrain、ChromaticAberration、SplitToning、LensDistortion、WhiteBalance、PaniniProjection、LiftGammaGain、ShadowsMidtonesHighlights、ColorCurves、ChannelMixer)
代码模板:
- references/code-templates.md — 全局Volume设置、相机后期处理及配置文件修改模板
3. Anti-Hallucination Rules
3. 防幻觉规则
Required Usings
必需的Using指令
These apply when you write a file into the project. A snippet passed to cannot
carry them — qualify the types instead (see "Passing C# to " above).
.csevalevalcsharp
using UnityEngine.Rendering; // Volume, VolumeProfile, VolumeComponent, VolumeParameter
using UnityEngine.Rendering.Universal; // Bloom, Tonemapping, ColorAdjustments, UniversalRenderPipeline, etc.这些指令适用于你写入项目的文件。传递给的代码片段不能包含这些指令——请改用类型限定(参见上方“向传递C#代码”部分)。
.csevalevalcsharp
using UnityEngine.Rendering; // Volume, VolumeProfile, VolumeComponent, VolumeParameter
using UnityEngine.Rendering.Universal; // Bloom, Tonemapping, ColorAdjustments, UniversalRenderPipeline, etc.Wrong → Correct API Mapping
错误→正确API映射
| WRONG | CORRECT |
|---|---|
| |
| |
| |
| |
| |
| |
| |
| 错误用法 | 正确用法 |
|---|---|
| |
| |
| |
| |
| |
| |
| |
Key Facts
关键事实
- is required on every
overrideState = trueyou set. The volume system skips parameters whereVolumeParameterisoverrideState. This is the #1 scripting mistake.false - = returns the asset directly (edits persist to disk).
sharedProfile= auto-clones into an instance if needed (safe for runtime edits). Check withprofile.volume.HasInstantiatedProfile() - — pass
profile.Add<T>(bool overrides = false)to auto-enabletrueon all parameters of the added component.overrideState
- ****是设置每个
overrideState = true的必需条件。Volume系统会跳过VolumeParameter为overrideState的参数。这是脚本编写中最常见的错误。false - = 直接返回资源(修改会持久化到磁盘)。
sharedProfile= 必要时自动克隆为实例(适合运行时修改)。可通过profile检查。volume.HasInstantiatedProfile() - — 传递
profile.Add<T>(bool overrides = false)可自动启用添加组件的所有参数的true。overrideState
4. Debugging Checklist
4. 调试清单
When post-processing isn't working, check in order:
- succeeds and
cam.TryGetComponent<UniversalAdditionalCameraData>(out var data)isdata.renderPostProcessing?true - Volume exists in scene with a non-null (or
profile) assigned?sharedProfile - Overrides added via AND
profile.Add<T>()on each property you set?overrideState = true - Volume's is included in camera's
GameObject.layer? (Default mask is layer 0 "Default" only.)data.volumeLayerMask - (for global), or camera is inside the Volume's trigger
volume.isGlobal = true(for local)?Collider - Camera is
data.renderType, notCameraRenderType.Base? (Overlay cameras composite onto the Base camera's output.)Overlay - is
UniversalRenderPipeline.asset.supportsHDR? Required for Bloom and Tonemapping.true - Viewing in Game view? Scene view has a separate post-processing toggle in its toolbar.
当后期处理无法正常工作时,请按以下顺序检查:
- 是否成功,且
cam.TryGetComponent<UniversalAdditionalCameraData>(out var data)是否为data.renderPostProcessing?true - 场景中是否存在已分配非空(或
profile)的Volume?sharedProfile - 是否已通过添加覆盖项,且每个设置的属性都已设置
profile.Add<T>()?overrideState = true - Volume的是否包含在相机的
GameObject.layer中?(默认遮罩仅包含0层“Default”。)data.volumeLayerMask - (全局Volume),或相机位于Volume的碰撞触发器
volume.isGlobal = true内部(局部Volume)?Collider - 相机的是否为
data.renderType,而非CameraRenderType.Base?(Overlay相机合成到Base相机的输出上。)Overlay - 是否为
UniversalRenderPipeline.asset.supportsHDR?这是Bloom和色调映射的必需条件。true - 是否在Game视图中查看?Scene视图的工具栏中有单独的后期处理开关。
5. Common Recipes
5. 常用配置方案
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.
格式:效果 属性=值。Bloom值格式为 threshold/intensity/scatter。
电影风格: 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
风格化/鲜艳风格: Tonemapping mode=Neutral, ColorAdjustments saturation=20 contrast=10, Bloom threshold=0.8 intensity=1.5 scatter=0.6, SplitToning highlights=暖色调 shadows=冷色调
恐怖/暗黑风格: ColorAdjustments postExposure=-0.5 saturation=-30 contrast=20, Vignette intensity=0.5 smoothness=0.3 color=深红色, FilmGrain type=Large01 intensity=0.4, ChromaticAberration intensity=0.15
简洁/移动端风格: Tonemapping mode=Neutral, ColorAdjustments postExposure=0.2, Bloom threshold=1.0 intensity=0.3(柔和效果)。移动端请避免使用FilmGrain、MotionBlur、DepthOfField。
6. Final Confirmation
6. 最终确认
After setup, report to user:
Post-Processing Setup Complete
- Volume: [Global/Local] on "[GameObject Name]"
- Profile: [Asset Path]
- Effects: [List with key property=value pairs]
- Camera: [Name] — renderPostProcessing=true, volumeLayerMask includes layer [N]
View results in Game view (not Scene view).
Undo all changes with Edit > Undo (Ctrl+Z).设置完成后,向用户报告:
后期处理设置完成
- Volume:[全局/局部],位于"[游戏对象名称]"
- 配置文件:[资源路径]
- 效果:[包含关键属性=值对的列表]
- 相机:[名称] — renderPostProcessing=true,volumeLayerMask包含第[N]层
请在Game视图中查看结果(而非Scene视图)。
可通过编辑 > 撤销(Ctrl+Z)撤销所有更改。