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

Help with Spherical Harmonics

Discussion in 'Scripting' started by a1733125, May 10, 2021.

  1. a1733125

    a1733125

    Joined:
    Mar 18, 2021
    Posts:
    4
    Hi everyone,
    I am struggling to understand why my output from Spherical Harmonics (Color) is not in the range of 0-1. I attached the script below. In some cases, if I moved the object near the light, it went over 2 or 3. If I moved far away, it reduced to between 0-1.
    Code (CSharp):
    1. public float GetProbe()
    2.     {
    3.         UnityEngine.Rendering.SphericalHarmonicsL2 sh2;
    4.         LightProbes.GetInterpolatedProbe(transform.position, null, out sh2);
    5.         Vector3[] directions = new Vector3[]
    6.         {
    7.             new Vector3(-1.0f/Mathf.Sqrt(6.0f),-1.0f/Mathf.Sqrt(2.0f),1.0f/Mathf.Sqrt(3.0f)),
    8.             new Vector3(-1.0f/Mathf.Sqrt(6.0f),1.0f/Mathf.Sqrt(2.0f),1.0f/Mathf.Sqrt(3.0f)),
    9.             new Vector3(Mathf.Sqrt(2.0f/3.0f),0,1.0f/Mathf.Sqrt(3.0f))
    10.         };
    11.         int size = directions.Length;
    12.         Color[] results = new Color[size];
    13.         //Normalize vectors as sh2 requirements
    14.         for (int i = 0; i < size; i++)
    15.         {
    16.             Vector3.Normalize(directions[ i ]);
    17.         };
    18.         //Evaluate
    19.         sh2.Evaluate(directions, results);
    20.      
    21.         for (int i = 0; i < size; i++)
    22.         {
    23.              Debug.Log(results[ i ]);
    24.         };
    25.     }
     
    Last edited: May 11, 2021
  2. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    3,446
    This part:
    doesn't make much sense and wouldn't even compile. Maybe it's missing some code? Please use code tags when posting code. Anyways I guess your
    [i]
    got swallowed as an BB italics tag (the closing bracket looks italic) however even when your code actually looks like this

    Code (CSharp):
    1. for (int i = 0; i < size; i++)
    2. {
    3.     Vector3.Normalize(directions[i]);
    4. }

    it doesn't make much sense. Vector3 is a struct. So passing a Vector3 value to a method can never modify the value you pass in. That's why the static method Vector3.Normalize returns the normalized vector. So you probably wanted to do

    Code (CSharp):
    1. for (int i = 0; i < size; i++)
    2. {
    3.     directions[i] = Vector3.Normalize(directions[i]);
    4. }
    or just like this:

    Code (CSharp):
    1. for (int i = 0; i < size; i++)
    2. {
    3.     directions[i] = directions[i].normalized;
    4. }
    which does the same thing but is a bit shorter.
     
    Last edited: May 11, 2021
  3. a1733125

    a1733125

    Joined:
    Mar 18, 2021
    Posts:
    4
    I have edited the original code with code tags. Sorry for that.
    For this part, the vectors are still normalised.
    Code (CSharp):
    1.         for (int i = 0; i < size; i++)
    2.         {
    3.             Vector3.Normalize(directions[ i ]);
    4.         };
    Even if I changed the code to this, it still has the same Color result.
    Code (CSharp):
    1. for (int i = 0; i < size; i++)
    2. {
    3.     Vector3.Normalize(directions[i]);
    4. [I][I]}[/I][/I]
    Sorry if I missed something but I am not an expert of C# as I only use Unity for my final year project in Civil. Any help would be great.
     
  4. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,336
    Yes, they are normalized and returned to you... and then you do nothing with them.

    Read what Bunny said above very carefully. Vector3 is a struct, which is a value type. You can't give it to someone and have them change it because you gave them a copy.

    Vector3.Normalize() accepts a Vector3 and RETURNS a Vector3 that is normalized.

    You are discarding this normalized vector.

    Vector3.Normalize does not "operate upon" the thing you pass in.

    This might suit your needs:

    Code (csharp):
    1. directions[i] = Vector3.Normalize( directions[i]);
    Note how I pass it in, then when I get it back, I assign it out to where it came from originally.

    If I give you a value type (such as a struct), I have given you a copy. Anything you do to that does NOT affect my original value type object.

    If I give you a reference type (like a class), I am giving you a pointer that lets you change that one same object. You and I will be referring to the same original object.

    Make sure you google value type vs reference type and nail that down firmly in your brain or you will have a very rough time.
     
  5. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    3,446
    Note I edited my last post since there were still some italics tags hidden that got copied from your code ^^. Are you sure you read my post carefully? The code you posted you said you changed your code to, is the same as you had. Also no, the code you posted does not normalize the vectors stored in the directions array. Vector3 are structs. Structs are value types which are always copied when you assign them to a variable or when you pass them to a method as parameter. Therefore the method Vector3.Normalize is absolutely not able to modify the vector stored in the array. As I said the method returns the normalized vector.
     
    Kurt-Dekker likes this.
  6. a1733125

    a1733125

    Joined:
    Mar 18, 2021
    Posts:
    4
    Sorry if I didn't make it clear. What I meant is even with the new code
    Code (CSharp):
    1. for (int i = 0; i < size; i++)
    2.         {
    3.           directions[i] = Vector3.Normalize( directions[i]);
    4.         };
    5.  
    6.         //Evaluate
    7. sh2.Evaluate(directions, results);
    The evaluate function of sh2 still gives me the result outside of 0-1.
     
  7. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    3,446
    Well, I haven't used LightProbes in Unity. However if you have HDR in mind, I don't see a reason why the returned colors should be clamped to the 0-1 range.
     
  8. a1733125

    a1733125

    Joined:
    Mar 18, 2021
    Posts:
    4
    No problem. Thanks for your help. I will try to look more into it