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. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

how to fit SphericalHarmonicsL2 in LightProbes

Discussion in 'Global Illumination' started by lythm, Jan 22, 2019.

  1. lythm

    lythm

    Joined:
    Jan 9, 2019
    Posts:
    2
    Hi:
    I'm trying to import some SH L2 lightprobe data generated by our custom renderer, but the result after reconstrution doesnt seem right.So I decided to run some tests.

    Test 1:

    Code (CSharp):
    1.  
    2. Color[] results = new Color[1];
    3. Vector3[] dirs = new Vector3[1];
    4. dirs[0].x = 0;
    5. dirs[0].y = 0;
    6. dirs[0].z = -1;
    7.  
    8. UnityEngine.Rendering.SphericalHarmonicsL2 tmp = new UnityEngine.Rendering.SphericalHarmonicsL2();
    9. tmp.Clear();
    10. tmp.AddDirectionalLight(dirs[0], Color.white, 1);
    11. results[0] = Color.black;
    12. tmp.Evaluate(dirs, results);
    13. Debug.Log(results[0]);
    the output color is RGBA(2, 2, 2, 1), should it be RGBA(1, 1, 1, 1)????

    Test 2:
    after observing the above output, I found sh[0,0] is 0.4705882
    The band0 coeffient should be 1.0/sqrt(4PI) * color, since the color is RGBA(1, 1, 1, 1), so the sh[0,0] should be 1/sqrt(4PI)
    or
    puntional light should be RGBA(PI, PI, PI, PI), sh[0,0] should be PI/sqrt(4PI)
    but none of the above fit.

    Test 3:
    I create a simple scene with only one probe, and one directional light with dir(0, 0, -1), color(RGBA(1, 1, 1))
    and bake the probe with unity progressive renderer.
    Evaluate with Vector3(0, 0, 1), gives value RGBA(1,1,1,1)
    baked with our renderer (pathtracer)
    Evaluate gives RGBA(2.901, 2.901, 2.901, 1.000)

    the coefficients is projected with the following code:
    Code (CSharp):
    1. __host__ __device__ __inline__ SH9 SH9Basis(const float3& dir)
    2.     {
    3.         SH9 sh;
    4.  
    5.         // band 0
    6.         sh[0] = 0.282095f;
    7.  
    8.         // band 1
    9.         sh[1] = -0.488603f * dir.y;
    10.         sh[2] = 0.488603f * dir.z;
    11.         sh[3] = -0.488603f * dir.x;
    12.  
    13.         // Band 2
    14.         sh[4] = 1.092548f * dir.x * dir.y;
    15.         sh[5] = -1.092548f * dir.y * dir.z;
    16.         sh[6] = 0.315392f * (3.0f * dir.z * dir.z - 1.0f);
    17.         sh[7] = -1.092548f * dir.x * dir.z;
    18.         sh[8] = 0.546274f * (dir.x * dir.x - dir.y * dir.y);
    19.  
    20.         return sh;
    21.     }
    Code (CSharp):
    1. __device__ __host__ __inline__ SH9Color SH9Irradiance(const float3& dir, const float3& radiance)
    2.     {
    3.         SH9 sh = SH9Basis(dir);
    4.         SH9Color shIrradiance;
    5.  
    6.         shIrradiance[0] = sh[0] * radiance * 1.0f;
    7.  
    8.         shIrradiance[1] = sh[1] * radiance * 0.666879f;
    9.         shIrradiance[2] = sh[2] * radiance * 0.666879f;
    10.         shIrradiance[3] = sh[3] * radiance * 0.666879f;
    11.  
    12.         shIrradiance[4] = sh[4] * radiance * 0.25f;
    13.         shIrradiance[5] = sh[5] * radiance * 0.25f;
    14.         shIrradiance[6] = sh[6] * radiance * 0.25f;
    15.         shIrradiance[7] = sh[7] * radiance * 0.25f;
    16.         shIrradiance[8] = sh[8] * radiance * 0.25f;
    17.  
    18.         return shIrradiance;
    19.     }
    please note that divide by PI is included in cosine lobe convolution

    is there anything that I missed?
    has any one succeeded in importing external sh data into Unity?
     
  2. fguinier

    fguinier

    Unity Technologies

    Joined:
    Sep 14, 2015
    Posts:
    146
    Hi lythm, It might be interresting to compare with the code we use for the CPU/GPU lightmappers both are available within the Unity install folder:
    CPU Lightmapper: Editor\Data\Resources\RLSL\Shaders\Accumulate.rlsl
    GPU Lightmapper: Editor\Data\Resources\OpenCL\kernels\commonCL.h
    In both case please look for `accumulateSH`
     
  3. lythm

    lythm

    Joined:
    Jan 9, 2019
    Posts:
    2
    There is a normalization factor that differs with our SH code, I tried to fit it into our code but the result didnt seem right, I'm going to review the whole process and try to figure it out.

    Thank you for the resource! Really helpful.
     
    fguinier likes this.
  4. Waffle1434

    Waffle1434

    Joined:
    Jun 1, 2016
    Posts:
    5
    This helped a ton, you guys might want to consider a more standardized naming scheme. From what I gather, this is what the coefficients translate to:
    index = n,m
    0 = 0,0
    1 = 1,-1
    2 = 1,0
    3 = 1,1
    4 = 2,-2
    5 = 2,-1
    6 = 2,0
    7 = 2,1
    8 = 2,2