Spherical harmonics

Enoki can efficiently evaluate real spherical harmonics basis functions for both scalar and vector arguments. To use this feature, include the following header file:

#include <enoki/sh.h>

The evaluation routines rely on efficient pre-generated branch-free code processed using aggressive constant folding and common subexpression elimination passes. Evaluation routines are provided up to order 10.

The generated code is based on the paper Efficient Spherical Harmonic Evaluation, Journal of Computer Graphics Techniques (JCGT), vol. 2, no. 2, 84-90, 2013 by Peter-Pike Sloan.

Note

The directions provided to sh_eval_* must be normalized 3D vectors (i.e. using Cartesian instead of spherical coordinates).

The Mathematica equivalent of the real spherical harmonic basis implemented in enoki/sh.h is given by the following definition:

SphericalHarmonicQ[l_, m_, d_] := Block[{θ, ϕ},
  θ = ArcCos[d[[3]]];
  ϕ = ArcTan[d[[1]], d[[2]]];
  Piecewise[{
    {SphericalHarmonicY[l, m, θ, ϕ], m == 0},
    {Sqrt[2] * Re[SphericalHarmonicY[l,  m, θ, ϕ]], m > 0},
    {Sqrt[2] * Im[SphericalHarmonicY[l, -m, θ, ϕ]], m < 0}
  }]
]

Usage

The following example shows how to evaluate the spherical harmonics basis up to and including order 2 producing a total of 9 function evaluations.

using Vector3f = Array<float, 3>;
Vector3f d = normalize(Vector3f(1, 2, 3));

float coeffs[9];
sh_eval(d, 2, coeffs);

// Prints: [0.282095, -0.261169, 0.391754, -0.130585, 0.156078, -0.468235, 0.292864, -0.234118, -0.117059]
std::cout << load<Array<float, 9>>(coeffs) << std::endl;

Reference

template<typename Array>
void sh_eval(const Array &d, size_t order, expr_t<value_t<Array>> *out)

Evaluates the real spherical harmonics basis functions up to and including order order. The output array must have room for (order + 1)*(order + 1) entries. This function dispatches to one of the sh_eval_* implementations and throws an exception if order > 9.

template<typename Array>
void sh_eval_0(const Array &d, expr_t<value_t<Array>> *out)

Evaluates the real spherical harmonics basis functions up to and including order 0. The output array must have room for 1 entry.

template<typename Array>
void sh_eval_1(const Array &d, expr_t<value_t<Array>> *out)

Evaluates the real spherical harmonics basis functions up to and including order 1. The output array must have room for 4 entries.

template<typename Array>
void sh_eval_2(const Array &d, expr_t<value_t<Array>> *out)

Evaluates the real spherical harmonics basis functions up to and including order 2. The output array must have room for 9 entries.

template<typename Array>
void sh_eval_3(const Array &d, expr_t<value_t<Array>> *out)

Evaluates the real spherical harmonics basis functions up to and including order 3. The output array must have room for 16 entries.

template<typename Array>
void sh_eval_4(const Array &d, expr_t<value_t<Array>> *out)

Evaluates the real spherical harmonics basis functions up to and including order 4. The output array must have room for 25 entries.

template<typename Array>
void sh_eval_5(const Array &d, expr_t<value_t<Array>> *out)

Evaluates the real spherical harmonics basis functions up to and including order 5. The output array must have room for 36 entries.

template<typename Array>
void sh_eval_6(const Array &d, expr_t<value_t<Array>> *out)

Evaluates the real spherical harmonics basis functions up to and including order 6. The output array must have room for 49 entries.

template<typename Array>
void sh_eval_7(const Array &d, expr_t<value_t<Array>> *out)

Evaluates the real spherical harmonics basis functions up to and including order 7. The output array must have room for 64 entries.

template<typename Array>
void sh_eval_8(const Array &d, expr_t<value_t<Array>> *out)

Evaluates the real spherical harmonics basis functions up to and including order 8. The output array must have room for 81 entries.

template<typename Array>
void sh_eval_9(const Array &d, expr_t<value_t<Array>> *out)

Evaluates the real spherical harmonics basis functions up to and including order 9. The output array must have room for 100 entries.