Search Unity

How to modify Post Processing Profiles in Script?

Discussion in 'Universal Render Pipeline' started by enslaved2die, Oct 10, 2019.

  1. enslaved2die

    enslaved2die

    Joined:
    Aug 13, 2017
    Posts:
    24
    So basically what I want to archive is a simple Camera Shake as a PostFX, Im only using the LensDistortion center value here to move the Image a bit.
    I used the HDRP Volume controls as a base, but the change to the profile is not happening at all, even when I try to set it to a constant value.
    Do I miss something?

    This is what I already have:

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.Rendering;
    5. using UnityEngine.Rendering.Universal;
    6.  
    7. public class CameraShake : MonoBehaviour
    8. {
    9.     Volume volume;
    10.     LensDistortion lensDistortion;
    11.  
    12.     public AnimationCurve animationCurve;
    13.  
    14.     // Start is called before the first frame update
    15.     void Start()
    16.     {
    17.         Volume volume = gameObject.GetComponent<Volume>();
    18.         LensDistortion tmp;
    19.  
    20.         if(volume.profile.TryGet<LensDistortion>( out tmp ) )
    21.         {
    22.             lensDistortion = tmp;
    23.         }
    24.     }
    25.  
    26.     [ContextMenu("Shake")]
    27.     void Shake()
    28.     {
    29.         if(lensDistortion != null)
    30.             StartCoroutine(AutoShake());
    31.     }
    32.  
    33.     IEnumerator AutoShake()
    34.     {
    35.         float progress = 0;
    36.         Vector2 center;
    37.  
    38.         while(progress < 1)
    39.         {
    40.             Debug.Log(progress);
    41.             progress += Time.deltaTime;
    42.             float x = Mathf.Lerp(0.5f, Random.Range(-0.5f, 2), animationCurve.Evaluate(progress));
    43.             float y = Mathf.Lerp(0.5f, Random.Range(-1.3f, 2), animationCurve.Evaluate(progress));
    44.             center = new Vector2(x, y);
    45.             lensDistortion.center = new Vector2Parameter(center, true);
    46.             yield return new WaitForSeconds(0);
    47.         }
    48.     }
    49. }
    btw I use like a PingPong AnimationCurve, so that the value is going back to 0.5f again.
     
  2. enslaved2die

    enslaved2die

    Joined:
    Aug 13, 2017
    Posts:
    24
    Edit: It seems like the profile values are changing, but they don't have any effect on the rendering. Somehow the PostFX Rendering is stuck when changing values with a script.
     
  3. wuzhouu3d

    wuzhouu3d

    Joined:
    Nov 3, 2014
    Posts:
    7
    Use 'profile' in the 'volume'. I post example code here. You can have a try.

    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.Rendering;
    3. using UnityEngine.Rendering.Universal;
    4.  
    5. public class VolumeTest : MonoBehaviour
    6. {
    7.  
    8.     private Volume v;
    9.     private Bloom b;
    10.     private Vignette vg;
    11.     // Start is called before the first frame update
    12.     void Start()
    13.     {
    14.         v = GetComponent<Volume>();
    15.         v.profile.TryGet(out b);
    16.         v.profile.TryGet(out vg);
    17.     }
    18.  
    19.     [ContextMenu("test")]
    20.     private void Test()
    21.     {
    22.         b.scatter.value = 0.1f;
    23.         vg.intensity.value = 0.5f;
    24.     }
    25.  
    26. }
     
  4. weiping-toh

    weiping-toh

    Joined:
    Sep 8, 2015
    Posts:
    192
    The actual Volume reference used during PP rendering is actually cached into a Stack, hence modifying the Volume Component or the profile during runtime will have no effect.
    Try using "VolumeManager.instance.stack". <--- This is what the PP pass actually uses.
     
  5. wuzhouu3d

    wuzhouu3d

    Joined:
    Nov 3, 2014
    Posts:
    7
    My code works fine.
     
  6. Arfus

    Arfus

    Joined:
    Mar 12, 2013
    Posts:
    29
    It depends on when you retrieve a reference to the profile. Once the camera with the profile attached to is created (the render camera), the profile is created as a new instance, which is then used in the stack. The original profile on your players camera is then replaced by the one used with the stack.

    This means, that if you retrieve a reference to your profile BEFORE the render camera is created. You won't get the correct reference to your object, as that one is going to end up being replaced.
    If you get the reference after the render camera is created. You will get the correct reference and can adjust all the settings you like.

    Now please note, I could be wrong with this. But that's what I've experienced so far.
     
  7. Sithdown

    Sithdown

    Joined:
    Aug 8, 2014
    Posts:
    10
    Same. I have tried all that was suggested here to no avail. How are we supposed to change overrides on runtime?
     
  8. Arfus

    Arfus

    Joined:
    Mar 12, 2013
    Posts:
    29
  9. Llama_w_2Ls

    Llama_w_2Ls

    Joined:
    May 16, 2020
    Posts:
    7
    Code (CSharp):
    1.     public PostProcessVolume volume;
    2.  
    3.     public PostProcessVolume volume;
    4.     public float BloomIntensityValue;
    5.     public Slider BloomIntensitySlider;
    6.  
    7.     public float BloomDiffusionValue;
    8.     public Slider BloomDiffusionSlider;
    9.     public void Update()
    10.     {
    11.         ChangeBloomIntensitySettings();
    12.         BloomIntensityValue = BloomIntensitySlider.value * 20;
    13.  
    14.         ChangeBloomDiffusionSettings();
    15.         BloomDiffusionValue = BloomDiffusionSlider.value * 10;
    16.     }
    17.     public void ChangeBloomIntensitySettings()
    18.     {
    19.         GameObject gameObject = GameObject.Find("Coloured Cubes");
    20.         volume = gameObject.GetComponent<PostProcessVolume>();
    21.         Bloom bloom;
    22.         volume.profile.TryGetSettings(out bloom);
    23.         bloom.intensity.value = BloomIntensityValue;
    24.     }
    25.     public void ChangeBloomDiffusionSettings()
    26.     {
    27.         GameObject gameObject = GameObject.Find("Coloured Cubes");
    28.         volume = gameObject.GetComponent<PostProcessVolume>();
    29.         Bloom bloom;
    30.         volume.profile.TryGetSettings(out bloom);
    31.         bloom.diffusion.value = BloomDiffusionValue;
    32.     }
    How to manipulate bloom intensity and bloom diffusion through scripting with a slider. Hope it helps, i don't really understand this override stuff but this works for me.

    The way it works is by finding the gameobject in my scene called "Coloured Cubes" (which contains my post process volume - reference the object in the inspector), setting the PostProcessVolume called volume to the PostProVolume of that gameObject and then allows me to edit the settings for effects attatched to the volume's post profile, for example in this case, BLOOM.
     
    Last edited: Jul 8, 2020
    marck_ozz likes this.
  10. IrtezaRmasud

    IrtezaRmasud

    Joined:
    May 19, 2020
    Posts:
    15
    Worked man! Thanks
     
  11. marck_ozz

    marck_ozz

    Joined:
    Nov 30, 2018
    Posts:
    107
    This is what I did for URP:

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.UI;
    5. using UnityEngine.Rendering;
    6. using UnityEngine.Rendering.Universal;
    7.  
    8. public class BloomControl : MonoBehaviour
    9. {
    10.     public Slider bloomSld;
    11.     public Volume volume;
    12.     private Bloom thisBloom;
    13.  
    14.  
    15.     public void BloomCtrl()
    16.     {
    17.         VolumeProfile proflile = volume.sharedProfile;
    18.  
    19.  
    20.         volume.profile.TryGet(out thisBloom);
    21.         thisBloom.intensity.value = bloomSld.value;
    22.  
    23.         if(bloomSld.value == 0)
    24.             thisBloom.active = false;
    25.         else
    26.             thisBloom.active = true;
    27.     }
    28. }

    Basicaly it takes the value from a slider and pass it to the bloom value, and if slider value equals to 0, it deactivate the bloom override. I hope it helps!
     
    ChunkyMuffin and ExtraCat like this.
  12. TubertMorti

    TubertMorti

    Joined:
    Apr 3, 2020
    Posts:
    4
    using UnityEngine;
    using UnityEngine.Rendering.PostProcessing;

    public class BloomEffector : MonoBehaviour
    {
    private PostProcessVolume volume;
    private Bloom bloom;
    public float value;

    void Start()
    {
    var getVolume = GetComponent<PostProcessVolume>();
    volume = getVolume;
    volume.profile.TryGetSettings(out bloom);
    }

    private void Update()
    {
    var value = this.value;
    bloom.threshold.value = value;
    }
    }
     
  13. ExtraCat

    ExtraCat

    Joined:
    Aug 30, 2019
    Posts:
    52
    Unity cannot find this namespace.


    While this works indeed, thanks.
     
  14. KillDashNine

    KillDashNine

    Joined:
    Apr 19, 2020
    Posts:
    453
    If your code is inside an asmdef, you need to manually reference Unity.PostProcessing.Runtime there.
     
  15. Hypertectonic

    Hypertectonic

    Joined:
    Dec 16, 2016
    Posts:
    75
    To get a VolumeProfile in URP you need to reference the Unity.RenderPipelines.Core.Runtime assembly.
     
    Chmyke likes this.
  16. Gofrisuto

    Gofrisuto

    Joined:
    Dec 14, 2022
    Posts:
    1
    I faced the same problem,, and searched for hours, tried many different codes, and didn't understand, why can't I see the change, if the values are changing. Than I realized that I hadn't enabled post processing on the camera: upload_2023-1-5_14-44-42.png
    Make sure to enable it IN EVERY SCENE. (At least in Universal Render Pipeline)
     
    Lanyard31 and roamerfree like this.
  17. dikrilmuttaqin122

    dikrilmuttaqin122

    Joined:
    Mar 4, 2023
    Posts:
    1
    Code (CSharp):
    1.    public PostProcessVolume volume;
    2.     public PostProcessVolume volume;
    3.     public float BloomIntensityValue;
    4.     public Slider BloomIntensitySlider;
    5.     public float BloomDiffusionValue;
    6.     public Slider BloomDiffusionSlider;
    7.     public void Update()
    8.     {
    9.         ChangeBloomIntensitySettings();
    10.         BloomIntensityValue = BloomIntensitySlider.value * 20;
    11.         ChangeBloomDiffusionSettings();
    12.         BloomDiffusionValue = BloomDiffusionSlider.value * 10;
    13.     }
    14.     public void ChangeBloomIntensitySettings()
    15.     {
    16.         GameObject gameObject = GameObject.Find("Coloured Cubes");
    17.         volume = gameObject.GetComponent<PostProcessVolume>();
    18.         Bloom bloom;
    19.         volume.profile.TryGetSettings(out bloom);
    20.         bloom.intensity.value = BloomIntensityValue;
    21.     }
    22.     public void ChangeBloomDiffusionSettings()
    23.     {
    24.         GameObject gameObject = GameObject.Find("Coloured Cubes");
    25.         volume = gameObject.GetComponent<PostProcessVolume>();
    26.         Bloom bloom;
    27.         volume.profile.TryGetSettings(out bloom);
    28.         bloom.diffusion.value = BloomDiffusionValue;
    29.     }
    How to manipulate bloom intensity and bloom diffusion through scripting with a slider. Hope it helps, i don't really understand this override stuff but this works for me.
     
  18. Lanyard31

    Lanyard31

    Joined:
    Apr 10, 2022
    Posts:
    2
    nooooo it can't be
    (thank you so much man)
     
  19. OswaldInstantClick

    OswaldInstantClick

    Joined:
    Jul 11, 2022
    Posts:
    1
    This is the only useful answer regarding the thread subject.