1. We've introduced thread tags, search within a thread and similar thread search. Read more here.
    Dismiss Notice
  2. 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
  3. 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
  4. We've released our first Timeline Experimental Preview, our new tool for creating cutscenes and more! To check it out click here.
    Dismiss Notice
  5. Unity 5.5 is now released.
    Dismiss Notice
  6. Check out all the fixes for 5.5 in patch releases 1 & 2.
    Dismiss Notice
  7. Unity 5.6 beta is now available for download.
    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:
    313
    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,438
  3. jack-riddell

    jack-riddell

    Joined:
    Feb 11, 2014
    Posts:
    313
    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,438
    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:
    313
    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.