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 create Segmented Light Falloff?

Discussion in 'Universal Render Pipeline' started by Croquet_Flamingo, May 20, 2022.

  1. Croquet_Flamingo

    Croquet_Flamingo

    Joined:
    Aug 7, 2020
    Posts:
    3
    Hi I am trying to make my game, which currently has realistic light falloff, look more segmented like the mock up I have. I'm currently rendering all my sprites in 3d (kinda like enter the gungeon) and using this shader graph I attached to make the material all of the sprites are using. And the light for the campfire (and most other lights) are point lights. Is there anything I could do in the shader graph to change the lighting, or something somewhere else?
     

    Attached Files:

  2. Matt-Cranktrain

    Matt-Cranktrain

    Joined:
    Sep 10, 2013
    Posts:
    129
    In realgameView.png and PixelScaleMockUp.png it looks like your camera is set to Orthographic, so I'm not convinced you ought to be using actual lights for this sort of thing because it's going to be one hundred times easier to simply overlay an image with your desired segmented light falloff, and recreate Photoshop's 'Overlay' layer mode with a shader or a shader graph. You could easily animate it for the flickering camp fire light.

    I do understand the "build the scene in 3d" approach though, because it makes the 3d maths of the gameplay much easier, especially collisions, and things like pathfinding are easier too. The difficultly with this for an Orthographic camera, however, is what happens when the light is physically behind a sprite character. If the light is behind a tree, for instance, the front face of the tree won't be lit, even a little bit, unless you write a custom shader for that.

    If you're convinced that real lights is the way to go for you, you can indeed alter the way light falls off in Unity URP; you'll need to customise the ShaderLibrary/RealtimeLights.hlsl file within the URP package. Something like this but with your desired 'step' fall off of the light.

    My guess is that the Enter The Gungeon devs did a lot of custom rendering work to get their desired visual aesthetic.
     
  3. Croquet_Flamingo

    Croquet_Flamingo

    Joined:
    Aug 7, 2020
    Posts:
    3
    the problem is that we achieved the lighting affect in the mock up by overlaying the entire scene in a blue tint, with that blue tint just being progressively subtracted as you get closer to the campfire. After a few hours of tinkering, I can't figure out how to recreate that without making a blue tint overlay for the entire map, which I would like to avoid if possible.

    I looked under the directory you specified and I couldn't find RealtimeLights.hlsl. I attatched a photo of what was in my folder "ShaderLibrary". I also checked to make sure URP was up to date and it was. Could I incorporate that function somewhere in the lighting hlsl? Or can i still find the RealtimeLights somewhere?

    Thank you so much for responding. You are saving me from a lot of frustration
     

    Attached Files:

  4. Matt-Cranktrain

    Matt-Cranktrain

    Joined:
    Sep 10, 2013
    Posts:
    129
    In classical 3D scenes you'd get the right night-time colours by changing the Ambient Light - the one that's exposed in the lighting window - from a script, tinting it with that blue colour. But in your case I guess you'd want to mask out the non-blue areas around the light, so that's not an option unless you go for a more heavy duty approach with custom shaders.

    Sounds like you're using a slightly older version of Unity and URP than I am - in Unity 2021.2 it's RealtimeLights.hlsl, but as you've guessed, the older equivalent is in Lighting.hlsl. I don't have the older version of Unity installed right now, but take a look at Lighting.hlsl and look for where
    half attenuation
    is defined, that's the calculation you need to begin adjusting.

    For reference, here's what I've got in my game, except just a simple linear fall-off:

    Code (CSharp):
    1.  
    2. // the old attenuation:
    3. //half attenuation = half(DistanceAttenuation(distanceSqr, distanceAndSpotAttenuation.xy) * AngleAttenuation(spotDirection.xyz, lightDirection, distanceAndSpotAttenuation.zw));
    4. // my new stuff:
    5. float range = rcp(distanceAndSpotAttenuation.xyz);  // reciprocal to get the range
    6. half attenuation = clamp(1.0f - (distanceSqr / range), 0.0, 1.0);  // linear attenuation, runs from 0 to 1
    actually let me have a crack at a stepped attenuation:

    upload_2022-5-23_19-10-35.png

    You can see the hard lines on the ground as the five steps fall off from the lamppost. Doesn't look great for my game, but you get the idea! That attenuation function looks like:

    Code (CSharp):
    1. float range = rcp(distanceAndSpotAttenuation.xyz);
    2. half attenuation =clamp(1.0f - (distanceSqr / range), 0.0, 1.0);
    3. int steps = 5;
    4. attenuation = round(attenuation * steps) / steps;
    One question I have, that I don't have the answer for, is how you can lock the lighting to the pixel grid that's defined by all your sprite graphics. I'm guessing what looks like a 16x16 sprite actually takes up hundreds of real screen pixels, and that's part of the aesthetic that you want to be consistent. Aside from the way the light currently falls off in a way you don't want, the Unity light also looks very 'high res'. Some pixel art games like Eastward or Octopath Traveller do a good job with high fidelity lighting, and it's probably easier to get that working technically, but that's slightly different from your mock up.
     

    Attached Files: