- Home /
Modifying the new Post-Processing Stack through code?
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?
Answer by JPhilipp · Mar 21, 2018 at 03:16 PM
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
I don't think this works with the current version of the PP stack.
I think its simply that some names have changed a bit
PostProcessProfile not PostProcessingProfile
also bloom, etc. isn't called out by name as far as I can see, insted we have a List of PostProcessEffectSettings and various funcitons to help find stuff in that list or if you know what index its at I suppose PostProcessProfile.settings[index] would work just fine.
is there an alternative for postprocessingbehavior? i tried postprocessbehavior. it dint work ;)
Indeed this won't work with PostProcessingStack v2... but now it is actually a lot more logical how it works. Now you get self-encapsulated settings objects from the profile asset assigned to the PostProcessVolume
by calling postProcessVolume.profile.TryGetSettings(out variableOfTypeOfSettingsYouWant)
. Then you can access its parameters by name of parameter and .value
.
Example:
PostProcessVolume activeVolume = ...;
if (activeVolume != null) {
Vignette vignette;
activeVolume.profile.TryGetSettings(out vignette);
if (vignette != null) { vignette.intensity.value = 0.675f; }
}
This isn't an answer. Saying something doesn't work now isn't constructive. Converting to comment.
Well, this is one way to do it, but this will create a run-time PostProcessVolume, one that you cannot edit when not in play mode. Ins$$anonymous$$d of instantating the Vignette scriptable object, you could have a PostProcessVolume asset in your project (with Vignette effect enabled on it), and use it in the script (as a reference or getting it from your PostProcess$$anonymous$$anager).
Ah, thanks... now it finally works for me! I might remove this answer and post my code in another answer, or maybe actually you wanna answer OPs question.
Editing your answer is better than deleting it.
The OPs answer is actually answered and there is an accepted answer, but it is about V1 of the PostProcessingStack. It is better to have an updated answer. If you write it, I will upvote it so that it gains visibility.
Answer by AurimasBlazulionis · May 19, 2017 at 05:51 AM
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:
1) Save a temporary effect like this: EffectModel.Settings effectSettings = profile.effect.settings
. Change the effect to the actual type.
2) Edit the settings.
3) Apply them back: profile.effect.settings = effectSettings
.
Keep in mind that it will permanently edit the settings of the profile.
Yep, this works! Here's a quick example of a specific setting change (Bloom intensity) through script:
using UnityEngine.PostProcessing;
public class BloomControl : $$anonymous$$onoBehaviour {
//remember to drag and drop your scriptable object into this field in the inspector...
public PostProcessingProfile ppProfile;
void Start() {
ChangeBloomAtRuntime();
}
void ChangeBloomAtRuntime()
{
//copy current bloom settings from the profile into a temporary variable
Bloom$$anonymous$$odel.Settings bloomSettings = ppProfile.bloom.settings;
//change the intensity in the temporary settings variable
bloomSettings.bloom.intensity = 2;
//set the bloom settings in the actual profile to the temp settings with the changed value
ppProfile.bloom.settings = bloomSettings;
}
}
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?
NOTE: It is also possible to do runtime-only changes, i.e. prevent messing with the Asset itself. Just instantiate your profile at runtime, and re-assign it. See here: https://github.com/Unity-Technologies/PostProcessing/wiki/(v1)-Runtime-post-processing-modification
Answer by warpfx · Apr 08, 2020 at 07:41 AM
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!
Thank you so much for this answer!! There's been so many changes to the Post Processing system that I've spent quite some time stumbling between different options. This works perfectly for those using URP. Thanks!!!
Thank you so much for that! it's the only thing I found to be working when trying to access PP via script with URP.
So it's changing the values correctly but I'm not sure what you meant by "ready to be animated"? I'm wondering how to animate between the values, like a simple lerp. There's not much documentation about that NoInterp$$anonymous$$inFloatParameter so if you could please explain and/or show a working animated example that would be absolutely amazing
Hi @Jassucks !
When you add PostProcessingData script into object containing Volume component, you can change chromaticAberrationIntensity value using Animation window:
Update() method is called every frame so the script will pick up current chromaticAberrationIntensity value and update Post Processing's chromatic aberration via chromaticAberration.intensity.SetValue(new NoInterp$$anonymous$$inFloatParameter(chromaticAberrationIntensity, 0, true));
Thus way you can animate Post Processing effects, e.g., make a heartbeat effect, or loose of player's focus.
Oh! i'm sorry lol, I completely forgot about animating with the Animation window. That should probably work just as good for me. Thanks again, this is super helpful! :-)
Answer by Wolfram · Aug 01, 2018 at 10:55 AM
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
Answer by idbrii · Mar 22, 2019 at 09:17 PM
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.
Your answer
Follow this Question
Related Questions
How to manipulate PostProcessing effects settings during execution with c#? 1 Answer
Changing URP Volume values in code not working 0 Answers
Creating Chalk-drawing Post Processing 0 Answers
How can I save and load a Coroutine state ? 0 Answers
Script To Update Post Process Profile At Runtime [2018 HDRP] 1 Answer