Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Problem with flickering ambient lighting in deferred passes

Discussion in 'Shaders' started by QwertyFighter, Jul 12, 2019.

  1. QwertyFighter

    QwertyFighter

    Joined:
    Feb 17, 2019
    Posts:
    5
    Hey everybody,

    I'm getting some annoying flickering using ambient light in my deferred shader. The flicker doesn't happen normally but whenever i move the camera in scene view or inspect a gameobject with the material it flickers back and forth to no ambient lighting and with then ambient.

    I think it may be because i have to use ambient within the actual internal deferred shading and not the initial buffer writing shader. I'm going for a cel shaded look, so when I go through the light passes I get the maximum of the color that's already there and the color I want to write using BlendOp Max.

    Cause of that i need to add ambient light to the light color like so:

    float3 steppedLight = (steppedLightAtten*light.color) + unity_AmbientSky; // UNITY_LIGHTMODEL_AMBIENT;

    Because otherwise any lights that are lower than the ambient light would be ignored.

    Now there are two ways I can think of to solve this.

    1. I use my own color(s) in the properties of the deferred shader as a lookup texture. This way I'll be able to edit it from script. Down side is it adds a little bit more complexity, and slows it down just a bit.

    2. I make a shader that goes after the final deferred light pass. This way I can use the stock ambient values without needing to add my own. I'd also be able to apply some small after effects very easily. Down side is I don't even know if this way would work.

    My problem is I don't even know where to start to work on these solutions.

    Any help to point me in the right direction, or suggesting a different approach would be appreciated!
     
  2. QwertyFighter

    QwertyFighter

    Joined:
    Feb 17, 2019
    Posts:
    5
    I've solved this now and I feel dumb.
    I set up a simple ambient light manager that contains the light color i want and put it on a gameobject in the scene.
    The code:
    Code (CSharp):
    1. [ExecuteInEditMode]
    2. public class AmbientManager : MonoBehaviour
    3. {
    4.     public Color ambientColor;
    5.     private int propertyID;
    6.     void Start()
    7.     {
    8.         propertyID = Shader.PropertyToID("_AmbientColor");
    9.     }
    10.     void Update()
    11.     {
    12.         Shader.SetGlobalColor(propertyID, ambientColor);
    13.     }
    14. }
    And I used the following inside my internal shader properties afer the gbuffer samplers:

    float4 _AmbientColor;

    and changed the steppedlight line to this:
    float3 steppedLight = (steppedAtten*light.color)+_AmbientColor;