Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Join us on Dec 8, 2022, between 7 am & 7 pm EST, in the DOTS Dev Blitz Day 2022 - Q&A forum, Discord, and Unity3D Subreddit to learn more about DOTS directly from the Unity Developers.
    Dismiss Notice
  3. Have a look at our Games Focus blog post series which will show what Unity is doing for all game developers – now, next year, and in the future.
    Dismiss Notice

Bug Local Volume blending not working with certain Post Processing Overrides (URP)

Discussion in 'Image Effects' started by Arbodon, Jul 27, 2021.

  1. Arbodon

    Arbodon

    Joined:
    Jul 2, 2020
    Posts:
    4
    I'm trying to fade in/out of a Color Lookup Override by setting a Post Processing Volume to Local, and using its Blend Distance and a Box Collider. However, instead of smoothly blending the effect, it simply snaps on and off with zero interpolation, as soon as the camera/player reaches the designated Blend Distance. I've tested all of the other overrides (to check for user error), and they all work as expected (blending smoothly), except for these three:

    Color Curves
    Color Lookup
    Tonemapping


    I thought that maybe you can't blend lookup textures. BUT, if you set the Color Lookup Contribution down to zero, there's an odd sort of 'inverse' blending happening: as the camera/player reaches the Blend Distance, the Color Lookup override snaps to 100% on, then blends smoothly all the way down to 0% as you approach/enter the collider. Then as you exit the collider, the effect smoothly blends all the way back up to maximum. Then snaps off as you exit the Blend Distance threshold. So it's obviously capable of blending—it just won't do it in the correct direction.

    I've tried messing around with the Volume Weight, but that has not produced any positive results.

    Also, oddly enough the Color Lookup override is not listed in the documentation:
    https://docs.unity3d.com/Packages/com.unity.render-pipelines.universal@11.0/manual/EffectList.html

    I'm using Unity 2021.1.12 and URP 11.0.0.

    Anyone have any thoughts or insight? Should I report this as a bug? I've tried everything I can think of, and scoured the internet for information and haven't found anything. Any help is greatly appreciated.
     
    Last edited: Jul 28, 2021
  2. lilacsky824

    lilacsky824

    Joined:
    May 19, 2018
    Posts:
    134
    Hi.
    I have similar problem with interpolation.
    After I check source code of URP.
    I found these effect use types of parameter that doesn't support interpolation.
    So they don't interpolation properly.

    There are some reasons will cause blending incorrect.
    Like effects' default value doesn't is not makes effect no effect at all.
    But it is found in custom PPv2 effect .Not sure URP's integrate post processing will have similar problem.

    lerp.jpg
     
  3. Arbodon

    Arbodon

    Joined:
    Jul 2, 2020
    Posts:
    4
    Hi, @lilacsky824 — Thanks for the reply.

    You've inspired me to also go digging through the source code, to try and better understand what's going on. You're right—I found the same thing on the TextureParameter, which is the VolumeParameter for the ColorLookup Component:

    TextureParameter.jpg

    That TextureCurveParameter in your screenshot is the VolumeParameter for the ColorCurves Component, so I guess that explains why that override won't blend. However, the ColorLookup Component also has a ClampedFloatParameter, which CAN be interpolated:

    ColorLookup_ClampedFloat.jpg

    Which makes me wonder why this float value can't be used for blending on the ColorLookup, but may explain the odd 'inverse' blending that I described in my original post.

    Anyway, thanks for the info! Hopefully the Unity team will get to these "TODOs" soon...
     
  4. coutlass-supreme

    coutlass-supreme

    Joined:
    Feb 21, 2014
    Posts:
    22
    Hi, Any news on this?
     
  5. Arbodon

    Arbodon

    Joined:
    Jul 2, 2020
    Posts:
    4
    Unfortunately not. At this point I'm just hoping that the Unity team is able to get to things marked as "TODO" for the next major update. I've not had the chance to dig much further. I was going to file a bug report, but I don't think it technically qualifies.
     
  6. ChaosResolution

    ChaosResolution

    Joined:
    Jan 22, 2013
    Posts:
    80
    Looking into this as well. Is it not possible to smoothly blend from ACES Tonemapping mode to a local volume which uses Neutral Tonemapping?
     
    Guillaume-atVolumiq likes this.
  7. Guillaume-atVolumiq

    Guillaume-atVolumiq

    Joined:
    Sep 14, 2018
    Posts:
    27
    Also looking for this.
     
  8. zephybite0

    zephybite0

    Joined:
    Apr 25, 2018
    Posts:
    27
  9. Arbodon

    Arbodon

    Joined:
    Jul 2, 2020
    Posts:
    4
    I finally found a way to blend between two lookup textures, after stumbling across this reddit post:

    https://www.reddit.com/r/gamedev/comments/jh70ij/is_it_possible_to_transition_from_one_lut_to/

    The solution shown there in the comments wasn't working as expected (well... I couldn't get it to work, rather), so I modified it and arrived at this simpler version:
    Code (CSharp):
    1. using System;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using UnityEngine;
    5. using UnityEngine.Rendering;
    6. using UnityEngine.Rendering.Universal;
    7.  
    8. public class LUTBlender : MonoBehaviour
    9. {
    10.     [SerializeField] Volume volume;
    11.     [SerializeField] Material lutBlendMaterial;
    12.     [SerializeField] Texture startingLut;
    13.     [SerializeField] Texture targetLut;
    14.  
    15.     RenderTexture mainRenderTexture;
    16.     ColorLookup colorLookup;
    17.  
    18.     void Start()
    19.     {
    20.         volume.profile.TryGet(out colorLookup);
    21.  
    22.         mainRenderTexture = new RenderTexture(1024, 32, 32, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear);
    23.  
    24.         lutBlendMaterial.SetTexture("_MainTex", startingLut);
    25.         lutBlendMaterial.SetTexture("_Texture2", targetLut);
    26.     }
    27.  
    28.     public void HandleLutBlend(float blendRatio)
    29.     {
    30.         lutBlendMaterial.SetFloat("_Blend", blendRatio);
    31.         Graphics.Blit(null, mainRenderTexture, lutBlendMaterial);
    32.         colorLookup.texture.value = mainRenderTexture;
    33.     }
    34. }

    I just created my own trigger zones, and then call that 'HandleLutBlend' method in Update with a Lerp function (of course making sure to start/stop it properly). It blends perfectly! I also added a few other simple methods for handling more than two luts, but the above script is the basic version.

    And here's the shader for the blend material:
    Code (CSharp):
    1. Shader "Hidden/LUTBlendShader"
    2. {
    3.     Properties
    4.     {
    5.         _MainTex("LUT1", 2D) = "white" {}
    6.         _Texture2("LUT2", 2D) = "white" {}
    7.         _Blend("Blend", Range(0, 1)) = 1
    8.     }
    9.         SubShader
    10.         {
    11.             Cull Off ZWrite Off ZTest Always
    12.  
    13.             Pass
    14.             {
    15.                 CGPROGRAM
    16.                 #pragma vertex vert
    17.                 #pragma fragment frag
    18.  
    19.                 #include "UnityCG.cginc"
    20.  
    21.                 #define COLORS 32.0
    22.  
    23.                 struct appdata
    24.                 {
    25.                     float4 vertex : POSITION;
    26.                     float2 uv : TEXCOORD0;
    27.                 };
    28.  
    29.                 struct v2f
    30.                 {
    31.                     float2 uv : TEXCOORD0;
    32.                     float4 vertex : SV_POSITION;
    33.                 };
    34.  
    35.                 v2f vert(appdata v)
    36.                 {
    37.                     v2f o;
    38.                     o.vertex = UnityObjectToClipPos(v.vertex);
    39.                     o.uv = v.uv;
    40.                     return o;
    41.                 }
    42.  
    43.                 sampler2D _MainTex;
    44.                 sampler2D _Texture2;
    45.                 float _Blend;
    46.  
    47.                 fixed4 frag(v2f i) : SV_Target
    48.                 {
    49.                   fixed4 t1  = tex2D( _MainTex, i.uv );
    50.                   fixed4 t2  = tex2D( _Texture2, i.uv );
    51.                   return lerp( t1, t2, _Blend );
    52.                 }
    53.                 ENDCG
    54.             }
    55.         }
    56. }

    I know very little about shaders, post processing, and rendering, so I can't speak to the performance of this solution, but it seems to be working just fine for my purposes. Hope it helps.