⚠ Preview docs — built from the develop branch and may be unstable. Go to the stable docs.

struct SphericalHarmonics

Spherical Harmonics are kinda like Fourier, but on a sphere. That doesn’t mean terribly much to me, and could be wrong, but check out here for more details about how Spherical Harmonics work in this context!

However, the more practical thing is, SH can be a function that describes a value over the surface of a sphere! This is particularly useful for lighting, since you can basically store the lighting information for a space in this value! This is often used for lightmap data, or a light probe grid, but StereoKit just uses a single SH for the entire scene. It’s a gross oversimplification, but looks quite good, and is really fast! That’s extremely great when you’re trying to hit 60fps, or even 144fps.

StereoKit’s SH format at a glance, both for this CPU side struct, and for the GPU side representation:

Choice SphericalHarmonics struct Shader constants
Basis phase No Condon-Shortley phase Same
Normalization Orthonormal, constants at eval time Constants pre-baked
Domain Radiance, no cosine lobe Irradiance, lobe baked in
Packing Bands ascending, RGB per coefficient 7 Vec4s, dot-product form

This struct is the CPU side format! Math and imports happen here, and StereoKit converts it to the baked shader form once per lighting change. With no phase factor, all basis signs are positive, so a light from above lands as a positive coefficient2 (the linear y term), and the linear band points toward the brightest region. Watch out when importing coefficients from elsewhere as many libraries (ARCore, DirectXMath) include the phase factor, flipping the odd terms (coefficients 2, 4, 6, and 8) relative to this. If imported lighting shows up rotated 180 degrees, with up reading as down, negate those four!

Instance Fields and Properties

   
Vec3 coefficient1 Band 0, the constant/ambient term.
Vec3 coefficient2 Band 1, the linear y term.
Vec3 coefficient3 Band 1, the linear z term.
Vec3 coefficient4 Band 1, the linear x term.
Vec3 coefficient5 Band 2, the xy term.
Vec3 coefficient6 Band 2, the yz term.
Vec3 coefficient7 Band 2, the 3z^2-1 term.
Vec3 coefficient8 Band 2, the xz term.
Vec3 coefficient9 Band 2, the x^2-y^2 term.
SHLight DominantLight The dominant directional light in this lighting data, the same derivation Lighting.MainLight uses! The direction is normalized, and the color is the projection matched directional component: the light you could remove from this SH, or add back on top of it.
Vec3 DominantLightDirection The direction the dominant light is traveling, pointing away from the light source, the opposite of SHLight.directionTo.
Vec3 DominantLightDirectionTo The direction toward the strongest light source in this lighting data, following the same convention as SHLight.directionTo. The value is normalized, and sampling the light’s color is sh.Sample(sh.DominantLightDirectionTo).

Instance Methods

   
SphericalHarmonics Creates a SphericalHarmonic from an array of coefficients. Useful for loading stored data!
Add Adds a ‘directional light’ to the lighting approximation. This can be used to bake a multiple light setup, or accumulate light from a field of points.
Brightness Scales all the SphericalHarmonic’s coefficients! This behaves as if you’re modifying the brightness of the lighting this object represents.
Sample Look up the color information in a particular direction: the irradiance for a surface whose normal faces that way.
SubtractLight Removes a directional light from this lighting data, clamped to the light actually present so the result stays physical. Pairs with DominantLight for splitting the dominant light out of an SH, the way Lighting.MainLight does.
ToArray Converts the SphericalHarmonic into an array of coefficients 9 long. Useful for storing calculated data!

Static Methods

   
FromLights Creates a SphericalHarmonics approximation of the irradiance given from a set of directional lights!




Found an issue with these docs, or have some additional questions? Create an Issue on Github!