Skip to content

There might be an error in SphericalHarmonics.slang #483

Description

@ATRi111

Falcor\Source\Falcor\Utils\Math\SphericalHarmonics.slang:

/**
 * Evaluates the spherical harmonics basis function Y_i at Cartesian coordinate p=(x,y,z) on the unit sphere.
 * @param[in] idx Sequential SH basis function index, where 0 <= idx < 16 (SH degree 3 and lower).
 * @param[in] p Cartesian coordinate p=(x,y,z) on the unit sphere.
 * @return Evaluated SH basis function.
 */
[BackwardDifferentiable]
float eval_SH(uint idx, float3 p)
{
    // Standard real SH basis. See https://en.wikipedia.org/wiki/Table_of_spherical_harmonics
    // Note that in Appendix A2 of Sloan 2008, "Stupid Spherical Harmonics (SH) Tricks",
    // the signs are reversed for basis functions with odd m. We're not using Sloan's definitions.
    // TODO: More general implementation that supports higher degrees.
    // clang-format off
    switch (idx)
    {
    // l = 0
    case 0: return 1.f / (2.f * M_1_SQRTPI);                // m = 0
    // l = 1
    case 1: return p.y * sqrt(3.f) / (2.f * M_1_SQRTPI);            // m =-1
    case 2: return p.z * sqrt(3.f) / (2.f * M_1_SQRTPI);            // m = 0
    case 3: return p.x * sqrt(3.f) / (2.f * M_1_SQRTPI);            // m = 1
    // l = 2
    case 4: return p.x * p.y * sqrt(15.f) / (2.f * M_1_SQRTPI);                 // m =-2
    case 5: return p.y * p.z * sqrt(15.f) / (2.f * M_1_SQRTPI);                 // m =-1
    case 6: return (3.f * p.z * p.z - 1.f) * sqrt(5.f) / (4.f * M_1_SQRTPI);    // m = 0
    case 7: return p.x * p.z * sqrt(15.f) / (2.f * M_1_SQRTPI);                 // m = 1
    case 8: return (p.x * p.x - p.y * p.y) * sqrt(15.f) / (4.f * M_1_SQRTPI);   // m = 2
    // l = 3
    case 9:  return p.y * (3.f * p.x * p.x - p.y * p.y) * sqrt(70.f) / (8.f * M_1_SQRTPI);  // m =-3
    case 10: return p.x * p.y * p.z * sqrt(105.f) / (2.f * M_1_SQRTPI);                     // m =-2
    case 11: return p.y * (5.f * p.z * p.z - 1.f) * sqrt(42.f) / (8.f * M_1_SQRTPI);        // m =-1
    case 12: return p.z * (5.f * p.z * p.z - 3.f) * sqrt(7.f) / (4.f * M_1_SQRTPI);         // m = 0
    case 13: return p.x * (5.f * p.z * p.z - 1.f) * sqrt(42.f) / (8.f * M_1_SQRTPI);        // m = 1
    case 14: return p.z * (p.x * p.x - p.y * p.y) * sqrt(105.f) / (4.f * M_1_SQRTPI);       // m = 2
    case 15: return p.x * (p.x * p.x - 3.f * p.y * p.y) * sqrt(70.f) / (8.f * M_1_SQRTPI);  // m = 3
    }
    // clang-format on
    return 0.f;
}

According to Wikipedia , the eval_SH function should use M_SQRTPI instead of M_1_SQRTPI.

I noticed that that in a previous modification, you replaced M_SQRT_PIf by M_1_SQRTPI. (Refer to the image below)
Image

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions