Hello! I’ve added the new post-processing stack to my game and it looks very good… However, I’d like to have settings in the menu to turn certain post-processing components on and off for those who have lower end graphics cards. How can I access, for example, the on-off toggle buttons on the PP Stack through code to accomplish this?
And for anyone ending up here looking to do this for the newer versions of the PostProcessing stack, here’s what works for me, with thanks to Harinezumi:
using UnityEngine.Rendering.PostProcessing;
// properties of class
public float bloom = 10f;
public float saturation = 5f;
Bloom bloomLayer = null;
AmbientOcclusion ambientOcclusionLayer = null;
ColorGrading colorGradingLayer = null;
// somewhere during initializing
PostProcessVolume volume = gameObject.GetComponent<PostProcessVolume>();
volume.profile.TryGetSettings(out bloomLayer);
volume.profile.TryGetSettings(out ambientOcclusionLayer);
volume.profile.TryGetSettings(out colorGradingLayer);
// later in this class during handling and changing
ambientOcclusionLayer.enabled.value = true;
bloomLayer.enabled.value = true;
bloomLayer.intensity.value = bloom;
colorGradingLayer.enabled.value = true;
colorGradingLayer.saturation.value = saturation;
// ... with some more checks to disable it fully where
// needed/ if 0
First import UnityEngine.PostProcessing
You need to have the PostProcessingProfile as a variable. If we call it profile
, then you can access it’s settings. If you want to enable bloom, then use profile.bloom.enabled = true
. If you need to change the settings of each effect then use this workflow:
-
Save a temporary effect like this:
EffectModel.Settings effectSettings = profile.effect.settings
. Change the effect to the actual type. -
Edit the settings.
-
Apply them back:
profile.effect.settings = effectSettings
.
Keep in mind that it will permanently edit the settings of the profile.
For the new Universal Rendering Pipeline, I was able to animate post-processing values via custom script added to the object containg Volume component (which contains all the effects). Here’s working code, ready to be animated:
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
using UnityEngine;
public class PostProcessingData : MonoBehaviour
{
private Bloom bloom = null;
private ChromaticAberration chromaticAberration = null;
public float chromaticAberrationIntensity;
// Start is called before the first frame update
void Start()
{
Volume volume = GetComponent<Volume>();
volume.sharedProfile.TryGet<Bloom>(out bloom);
volume.sharedProfile.TryGet<ChromaticAberration>(out chromaticAberration);
}
// Update is called once per frame
void Update()
{
if (chromaticAberration != null)
{
chromaticAberration.intensity.SetValue(new NoInterpMinFloatParameter(chromaticAberrationIntensity, 0, true));
}
}
}
Changing intensity by property accessor didn’t work and SetValue()
was needed.
Hope it will be helpful for someone!
For Post-Processing v2, there is actually a Unity docs page that describes exactly the method to creat Volumes on-the-fly, or to manipulate existing profiles either temporarily during Play mode, or permanently:
https://docs.unity3d.com/Packages/com.unity.postprocessing@2.0/manual/Manipulating-the-Stack.html
can confirm the above example script does work. Currently using the most recent version of PP stack from unity.
Share an example of your script so we can help diagnose the issue?
As an extension of JPhilipp’s great answer, here’s a more complete code sample
for toggling effects “ApplySettings” function.
There isn’t a global method for adjusting effects, but we can force each volume
to have its own configuration. Since PostProcessVolume.profile creates a
volume-local profile, we can modify that and keep the sharedProfile as a
reference for the tuned value.
public void ApplySettings()
{
bool use_ambient_occlusion = PlayerPrefs.GetInt("use_ambient_occlusion") > 0;
bool use_auto_exposure = PlayerPrefs.GetInt("use_auto_exposure") > 0;
// ...
// Get all volumes (even inactive ones). Assuming you're not
// using QuickVolume, you can cache this list.
var all_volumes = FindAll<PostProcessVolume>();
foreach (var volume in all_volumes) {
var vanilla = volume.sharedProfile;
if (vanilla == null) {
continue;
}
var active = volume.profile;
ApplyRestriction<AmbientOcclusion>(vanilla, active, use_ambient_occlusion);
ApplyRestriction<AutoExposure>(vanilla, active, use_auto_exposure);
// ...
}
}
void ApplyRestriction<T>(PostProcessProfile vanilla, PostProcessProfile active, bool is_allowed)
where T : PostProcessEffectSettings
{
T vanilla_layer = null;
T active_layer = null;
vanilla.TryGetSettings(out vanilla_layer);
active.TryGetSettings(out active_layer);
if (vanilla_layer != null && active_layer != null)
active_layer.enabled.value = is_allowed && vanilla_layer.enabled.value;
}
FindAll<T>()
could be something like Resources.FindObjectsOfTypeAll<T>()
, but in editor, it finds assets , so you need an editor implementation too.
These effects have additional options to scale quality:
- AmbientOcclusion
- Bloom
- ChromaticAberration
- MotionBlur
- ScreenSpaceReflections
You’d need to special case them in the for loop.
Undiging this one
i can’t get a solution with what have been written above.
for a purpose i need to enable disable only the color grading
it should be very simple to access it and yet cant find a simple way
this page didn’t help me very much Manipulating the Stack | Package Manager UI website
any idea ?
I don’t think this works with the current version of the PP stack.