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. Dismiss Notice

Question How to have different Environment Lighting for certain objects?

Discussion in 'Universal Render Pipeline' started by JoeStrout, Feb 17, 2023.

  1. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,841
    At one point in our game, we want to turn down the lights all the way on the background and focus on the characters. Obviously this is easy to do with light objects in the scene (we can use the Culling Mask to have different lights for background vs characters). But it's nowhere near enough, because the Environment Lighting (i.e. ambient light) is still lighting up everything.

    Is there any way to specify different ambient (environment) light for different layers?

    I even tried adding a script to some objects that changes RenderSettings.ambientIntensity in OnPreRender (and changes it back in OnPostRender), but this has no apparent effect.

    The best we can come up with at this point is to use custom shaders on all the background objects, that apply a global multiplier to the final color. But that seems heavy-handed and quite limiting.

    Any other ideas?

    P.S. This is on mobile, so we need a solution that is as efficient as possible.
     
  2. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,841
    No ideas? :(
     
  3. Farsam

    Farsam

    Joined:
    Jul 24, 2023
    Posts:
    6
    good question I want to know it too
     
  4. OccaSoftware

    OccaSoftware

    Joined:
    May 24, 2019
    Posts:
    29
    Hi!
    Afaik, no in-built way to do this.
    I would recommend extending Unity's shader. Add an "Ambient Light Layer" (int) property. And add an "Ambient Light Intensity" (float array) property. Use it to attenuate environmental lighting. Then, set the ambient light intensity float array from a scene-level Monobehaviour. Iterate the array like a light loop.

    Alternatively, you can write a post-process effect. In the effect, you could stencil the characters. Then, fade the rest of the geometry to black. Might have challenges with transparent materials.
     
    Farsam and ElevenGame like this.
  5. ElevenGame

    ElevenGame

    Joined:
    Jun 13, 2016
    Posts:
    143
    You could use a custom shader on your characters instead, a shader that either ignores ambientIntensity value or can be fed a custom environment reflection cubemap. Then you could turn down ambientIntensity without it affecting your characters.
    If you put a reflection probe in your scene, that is low importance, only samples the sky and covers the whole level, you can basically rebuild a custom ambient probe. I'd suggest doing that at least during development, you can more easily see the cubemap texture it produces, bake whenever, etc. The Sky Managers internal probe (unity_SpecCube0) is kind of hidden. You could also use a similar kind of probe with zero size (not covering any objects) to sample the original environment reflections even though ambientIntensity is turned down.
    The most efficient way I think would be the character shader that ignores the ambientIntensity value, in which case you don't actually need any of the aforementioned probes, but I they can be useful visualization while building such a shader.
     
    Farsam likes this.