Search Unity

Spherical Harmonics, Custom Lighting models and Making sense of all this

Discussion in 'Shaders' started by Dorodo, May 22, 2017.

  1. Dorodo

    Dorodo

    Joined:
    Mar 8, 2015
    Posts:
    44
    I've been struggling at trying to make sense of including SH calculations inside a custom lighting model for our project.

    First, let me explain what is going on. As a disclaimer, I'm pretty much a beginner when it comes to shaders and most of the logic is being done in ShaderForge (we plan on rewriting the shaders later on, but that should do for now. Besides, I don't believe this is an asset related question, so please bear with me)



    So, we're working on a project which is trying to emulate a flat-ish lighting style, and after some tweaks, got a custom lighting model we were happy with. However, I found out later that light probe contribution would need to be added manually in the shader, so I did some research and found about the ShadeSH9 function in UnityCGIncludes (page 44), which you can also read about in the Unity Docs.


    I did get it to work on a test shader in shaderforge by adding a custom code with the object normal direction as input (image taken by zaza)



    This definitely was what I was looking for! However, the light probe contribution kinda works in a lambertian-ish way, so our custom lighting would get ruined if we simply added that result on top of our current lighting calculation



    Worst thing is, from what it looks like, the ShaderSH9 gives a float3 (RGB) result already, meaning I can't split light and color information into 2 separate passes, use the light contribution as a float1 value, mix it with the other tweaks and multiply by that light probe color contribution in the end. At least, I have no idea how to do that.

    Can anyone help me solve this dilemma? I would love to use light probes in our custom lighting since it would be a pain to bake the lightmaps, set the lights back to realtime, cull them so they only light the character and redo everything everytime we need a new bake.
     
  2. neoshaman

    neoshaman

    Joined:
    Feb 11, 2011
    Posts:
    6,493
    I'm not sure I follow this:
    - you want to split light into "intensity" and "light color"
    - use "intensity" as a value to mix with other data
    - blend it back with "light color"

    That does not make sense because light IS color.

    What's happening generally is that we use "analytical light" that generate "intensity" that does not correspond to any reality (ie it's not emitting, it's a mathematical abstraction that use correlation of property).

    Spherical harmonics isn't light proper, it's a 2 dimensional functions that abstract lighting contribution int one point. Ie another mathematical abstraction. They are incompatible with typical abstraction (like point to normal use for other light) because they have no concept of direction of light, just direction of "reception" (the angle relative to the normal).

    The spherical harmonics give the smooth contibution of bake light into one point using the 3 color components. In order to have flat look you need to:
    - proceed like with typical ndotl (lambert) light and pass the data through a step function, which would give you three flat contribution.
    - Compute the luminosity of all light contribution using luminosity = (Red * 0.039) + (Green * 0.458) + (Blue * 0.006) to get an intensity and use that like you want.
     
    wagner_de_souza likes this.
  3. Dorodo

    Dorodo

    Joined:
    Mar 8, 2015
    Posts:
    44

    Hey Neoshaman! Thank you for your reply and your explanation.

    Although it does make sense that in real life light does not work that way, I was suggesting a way to make that workflow work because it would give more artistic control over each separate pass, no?

    Something else I don't understand is how the standard shader can still add smoothness and metallic properties if you can't make a blinn-phong reflectivity with the light probe output...

    We're using Inside's Bounced Lighting model multiplied by a traditional lambertian formula instead of steps so we don't have that sharp cel-shaded shadow, so I'll do some tweaks and post an update later trying to use the light probe as a base for the rest instead of just trying to mix it later into the rest.
     
  4. neoshaman

    neoshaman

    Joined:
    Feb 11, 2011
    Posts:
    6,493
    Oh it's a half lambert lol wasn't sure what bounce was for lol, old trick new name lol I have a thread on tigsource that collect some trick: https://forums.tigsource.com/index.php?topic=32227.0

    Well speclight tend to use a principal light(s) and have everything else as secondary hacked :p And generally spec is handled using cubemap anyway so no nice overblown light. Spherical harmonics (like cubemap) can potentially hold infinite number of light sources only limited by their resolution.

    Since shader is something you do for yourself, feel free to add a custom direction, a specific light or any hack to get the result you want!

    I also really interested in various cel shading rendering, especially those who use a texture of hash to mask the spec! Or removing lambert altogether and using the light fall off only (or mixing the two for extra illustrative effects). I'm also especially appreciative of god level of guilty gear Xrd.

    I hope you post result of what you obtained :)
     
  5. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,343
    For this kind of style you really want to use the SH / light probes for just ambient lighting and keep the main light separate so you can do proper shadowing. For a flat shading using the existing probes you'll want to sample them with a fixed direction, or a few fixed directions, rather than using the surface normal. It all depends on your scene and the lighting you intend to have.

    The easiest case is just using ShadeSH9(half4(0,1,0,1)), which will get the lighting looking straight "up". You could also try to use the view direction, or maybe the negative view direction, or the main light direction, or even the camera facing direction (though I don't remember what nodes Shader Forge gives you).

    The next step is trying to sample ShadeSH9 from two directions, say up and down, and using the average. The best results will be sampling in at least 4 directions like from the points of a tetrahedron.

    If you want some amount of definition in the shadowed side, you might try lerping between two directions, or having an ambient occlusion texture / vertex color.
     
    kosowski likes this.
  6. wagner_de_souza

    wagner_de_souza

    Joined:
    Apr 9, 2019
    Posts:
    15
    Hi everyone
    Is it possible to change/set a "color" for a specific lightprobe?
    For example, I have a city and Im baking the external lightining and the lightprobes, but for the interior of the buildings I want a fixed color for the lightprobe. The interior are not being affect by the external light.
    Or, another example, I want to turn on/off a lightprobe of a light pole. Im not using dinamic lights or rebaking the light every time.
     
  7. POOKSHANK

    POOKSHANK

    Joined:
    Feb 8, 2022
    Posts:
    289