Change Post Processing Values on runtime.

I want to change the Color Grading values of the Post Processing Profile on Runtime.

At first I tried setting the values of the actual profil:
profile.colorGrading.settings.basic.contrast = 0;

but that doesn’t work.

So I tried setting it on the behavior it self but that didn’t work as well:
behavior.GetComponent().model.settings.basic.contrast = 10;

how exactly can I change the Post Processing on runtime?

I found the solution:

1 Like

The solution linked above (replace the profile with an instanced copy OnEnable, then edit that on Update), results in Post Processing Behaviors with null Profiles in Unity 5.6.2p2. It seems to only happen if the camera is inside a prefab, and might have something to do with the way cameras are handled by SteamVR.

My solution is to check every PostProcessingBehaviour on EditorApplication.playmodeStateChanged and set any null profiles I find. Code (must be in an Editor folder):

using UnityEngine;
using UnityEditor;
using UnityEditor.SceneManagement;
using UnityEngine.PostProcessing;

[InitializeOnLoad]
public class EditorManager {
    static EditorManager() {
        EditorApplication.playmodeStateChanged += FixMissingPostProcessingProfiles;
    }

    static void FixMissingPostProcessingProfiles() {
        PostProcessingBehaviour[] behaviors = Resources.FindObjectsOfTypeAll<PostProcessingBehaviour>();
        foreach (PostProcessingBehaviour behavior in behaviors) {
            if (behavior.profile == null) {
                Debug.LogWarning("PostProcessingProfile disconnected, reconnecting " + behavior.GetPath());
                behavior.profile = Resources.Load("MyPostProcess") as PostProcessingProfile;
            }
        }
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.PostProcessing;
public class BlurryEffect : MonoBehaviour
{
    //remember to drag and drop your scriptable object into this field in the inspector...
    public PostProcessingProfile ppProfile;
    public float changeValue;
    void Update()
    {
        ChangeDepthOfFieldAtRuntime(changeValue);
        ppProfile.depthOfField.enabled = true;
     
    }
    void ChangeDepthOfFieldAtRuntime( float val)
    {
        //copy current "depth of field" settings from the profile into a temporary variable
         DepthOfFieldModel.Settings deaptoffieldSettings = ppProfile.depthOfField.settings;
        deaptoffieldSettings.aperture += Time.deltaTime * val;
        //set the "depth of field" settings in the actual profile to the temp settings with the changed value
        ppProfile.depthOfField.settings = deaptoffieldSettings;
    }
 
}

}

Thank me later :slight_smile:

1 Like

thank you so much i had to make some small changes but overrall it worked perfectly

Sadly this doesn’t work for PPSV2 :confused:

I’m possibly using the most recent version of the post processing package - July 2020:
I’ve found a way to edit the settings of your post process volume, and any effects inside of it. None of the answers above were working for me, since unity removed BloomModel.settings from the newest stack and other issues, so I was able to come up with a script that is able to lower the intensity of your bloom by calling the function whenever i press a button.
using UnityEngine;
using UnityEngine.Rendering.PostProcessing;
public class BloomSettings : MonoBehaviour
{
public PostProcessVolume volume;
public void ChangeBloomSettings()
{
Bloom bloom;
volume.profile.TryGetSettings(out bloom);
bloom.intensity.value = 5f;
Debug.Log(“Working…”);
}
}
Make sure that you reference the post process volume in the inspector. Thanks to all the answers above for assisting!

4 Likes

I’m back with the new version (Nov 2020) and this time I needed post process effects that fade in over a few seconds.

PostProcessVolume.weight works (most of the time) if you want to fade in ALL the effects, but if you only want to change one, here’s how I do that, by using the original shared profile as the “max” value, 0 as the “min”, then using that to change the instanced profile as percent goes from 0 to 1:

private void SetEffectAlpha<T>(float percent) where T : PostProcessEffectSettings {
   volume.sharedProfile.TryGetSettings(out T effectShared);
   volume.profile.TryGetSettings(out T effectInstance);
   if (effectShared == null || effectInstance == null) {
      Debug.LogError("BackgroundEffects failed to get effect, " + typeof(T) + ", " + volume.sharedProfile?.name);
      return;
   }

   switch (effectShared) {
      case Bloom bloomShared when effectInstance is Bloom bloomInstance:
         bloomInstance.intensity.value = bloomShared.intensity.value * percent;
         break;
      case Ripples ripplesShared when effectInstance is Ripples ripplesInstance:
         ripplesInstance.strength.value = ripplesShared.strength.value * percent;
         break;
      case RadialBlur radialShared when effectInstance is RadialBlur radialInstance:
         radialInstance.amount.value = radialShared.amount.value * percent;
         break;
      case ColorSplit splitShared when effectInstance is ColorSplit splitInstance:
         splitInstance.offset.value = splitShared.offset.value * percent;
         break;
      default:
         Debug.LogError("BackgroundEffects unknown effect, " + typeof(T) + ", " + volume.sharedProfile?.name);
         break;
   }
 
   Debug.Log("=== SetEffectAlpha " + typeof(T) + ", " + percent);
}

This uses effects from a plugin (SC Post Effects) but just add a case for whatever effect you need to change the “intensity”, “strength”, “amount”, “offset”, “alpha” or whatever the heck variable can be dialed down to 0 to hide the effect.

Another fine rigamarole: if you need to change a PostProcessVolume’s entire profile at runtime, you should apparently do:

RuntimeUtilities.DestroyProfile(volume.profile, true);
volume.sharedProfile = newProfile;
volume.profile = null;
PostProcessProfile junk = volume.profile;

First line prevents a memory leak.

Last two lines replace volume.profile with an instanced copy of the sharedProfile, which you can edit at runtime without screwing up the original one in your file system.

Would love to know any simpler way to switch profiles or fade a full stack of PostProcess effects in and out as my solutions feel convoluted but I could not find a better way.

1 Like

I brought this up in another thread about how this system deals with priority and global volumes in the context of cinemachine.

They really need to add a better way to manage these things.
Feedback - Post process stack integration flaw with priority, toggling effects - Unity Forum

Not sure if anyone needs this but i did somethign similar to vignette with URP

private Vignette GetVignette()
{
for (int i = 0; i < volume.profile.components.Count; i++)
{
if(volume.profile.components is Vignette)
{
return (Vignette)volume.profile.components*;*
}
}
return null;
}

1 Like