1. Help us improve the editor usability and artist workflows. Join our discussion to provide your feedback.
    Dismiss Notice
  2. We're looking for feedback on Unity Starter Kits! Let us know what you’d like.
    Dismiss Notice
  3. We’re giving 2017.1 beta testers a chance to win t-shirts and a Nintendo Switch. Read more on the blog.
    Dismiss Notice
  4. Unity 2017.1 beta is now available for download.
    Dismiss Notice
  5. Unity 5.6 is now released.
    Dismiss Notice
  6. Get further faster with the Unity Plus Accelerator Pack, free for new Unity Plus subscribers for a limited time. Click here for more details.
    Dismiss Notice
  7. Check out all the fixes for 5.6 on the patch releases page.
    Dismiss Notice
  8. Learn how you'll soon be able to publish your games to China in four simple steps with Xiaomi. Sign up now for early access.
    Dismiss Notice

GetInterpolatedLightProbe() interpreting the coefficients

Discussion in 'Shaders' started by jack-riddell, Mar 15, 2017.

  1. jack-riddell

    jack-riddell

    Joined:
    Feb 11, 2014
    Posts:
    322
    I seem to have run into a bit of an Information black hole related to interpreting the light probe returned from the GetInterpolatedLightProbe() function.

    there are a couple of threads related to this topic already which i have listed below but there doesn't seem to be a correct solution to the problem yet.

    https://forum.unity3d.com/threads/getinterpolatedlightprobe-interpreting-the-coefficients.209223/
    https://forum.unity3d.com/threads/lightprobes-getinterpolatedprobe-includes-dynamic-lights.311097/

    How do you take the values returned from GetInterpolatedLightProbe() and use them to calculate a light value for a given direction?

    under the hood unity seems to be using the code described here
    http://www.ppsloan.org/publications/StupidSH36.pdf
    in the UnityCG.include file there is a function called "ShadeSH9(Normal)" that matches the function described in the above publication but the steps described in "StupidSH36" to prepare the coefficients for the "ShadeSH9(Normal)" function don't work correctly.


    my issue is I need to render/calculate multiple direct/dynamic light lights as well as calculate ambient occlusion/light probe data in a single vertex lit pass (no lighting calculations in fragment and no multiple passes).
    At the moment my shader uses a LightMode = "Vertex" pass tag to get 8 dynamic light values which unity passes in using the "unity_LightPosition[]" arrays. However in LightMode = "Vertex" passes unity does not pass in the spherical harmonics which I need for baked lighting or global illumination/ambient lighting.
    My solution to this problem is to get the spherical harmonics using GetInterpolatedLightProbe() and pass it in to the shader manually but I am having trouble decoding the coefficients correctly.
    At the moment my shader sort of decodes the spherical harmonics but has issues with colour saturation and brightness.


    multiple directional lights using the 8 light values passed in when in LightMode = "Vertex".
    both the dynamic and spherical harmonic lighting can run at the same time provided they are passed in.
    [​IMG]

    particle system being lit by emissive lighting baked into light probes and passed to the material using GetInterpolatedLightProbe().
    you can sort of see the errors from my hack of the sperical harmonics here, the colours are off and not transitioning smoothly.
    [​IMG]


    Close up of a particle system being lit from a single directional light.
    [​IMG]

    If anyone knows any additional information about the format of the data returned by GetInterpolatedLightProbe() or how to translate the Spherical Harmonic components into something I can decode in a shader that would be very helpful.
     
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    2,683
  3. jack-riddell

    jack-riddell

    Joined:
    Feb 11, 2014
    Posts:
    322
    That is the code I am currently using but the output is not matching the lighting of other objects in the scene.

    the 2 spheres at the top are the light probes the bottom left sphere is using the light probe utility code and the bottom right is using the mobile defuse shader. As you can see the light probe utility code is darker and bluer than the light probe.

    LightProbe.png
     
  4. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    2,683
    Hmm, they changed a bunch of stuff in how the probes work for 5.3 or so, so they may have changed the encoding / decoding since that utility was written. :/
     
    jack-riddell likes this.
  5. jack-riddell

    jack-riddell

    Joined:
    Feb 11, 2014
    Posts:
    322
    Ok so after some extensive research I found the problem and it was a mistake on my end. Normally when dealing with float4 vectors in a shader if it is a direction vector you set the w value to 0 if it is a position you set the w value to 1. the ShadeSH9(Normal) function requires the w value to be set to 1 but due to my overconfidence I was passing in the normal with a w value of 0. The weird thing is this mostly works the colours are just a bit off which is why I thought it might be due to the way I was decoding the Coefficients. there are still some minor differences between the 2 but i think that might just be rounding errors and floating point inaccuracy.
     
    bgolus and richardkettlewell like this.