What are advantages of using spherical harmonics instead of irradiance cubemap? Are there any common used methods for conversion?


General Description

Quick Note irradiance maps are the image of the world around a point (environment map) which has been recalculated so each pixel is actually the sum of incident lighting on a surface with a given normal. When given a surface you can use the normal to do a texture lookup to get the indirect illumination value.

OK, so your irradiance cubemap is most likely stored as some form of compressed image.

One common lossy compression method for images is to do a fourier transform on the data and store the results. The fourier transform maps a waveform to a series of functions so we can compress a waveform to a simple set of coefficients. You can look at each colour channel as a waveform from the first pixel to the last which is why this works.

The spherical harmonic is essentially the same thing. The difference is that it's a mechanism for doing this process with functions which lie on a sphere rather than a 2D wave form.

In this respect, they're not really different, they are just different ways of encoding image data. Ofcourse, when we talk about using them we talk like they are completely different things, because we use them differently.

To put this simply, it's not really SH vs I cubemap, we're really talking about irradiance maps stored as spherical harmonics vs irradiance maps stored in a cubemap texture.

Advantages of SH

If you're using an irradiance map, you probably loading the image in then working with the image uncompressed and doing texture lookup based on surface normal. Typically with SH you are only loading and storing the coefficients and uncompressing the stored image when needed using these coefficients. So it has a smaller memory footprint.

It is, of course possible to map the entire image to a small set of compressed data and use that in the same way, but if you're doing that, spherical harmonics are easier to work with and probably work better given that they are designed for just this kind of data set.

The main impact of this smaller memory footprint is that you can use a lot more of them, so instead of one map for each scene, you can have one set of coefficients for every vertex of every object or cubic volume in the scene - which gives less detail than the environment map but a better representation across the scene geometry as it can vary more.

Of course any advantage really does depend on what you want to get on the screen and what your requirements are.

Check out this paper - "Using an analytic expression for the irradiance in terms of spherical harmonic coefficients of the lighting, we show that one needs to compute and use only 9 coefficients, corresponding to the lowest-frequency modes of the illumination".

In other words, irradiance maps don't vary a lot, they're low frequency, so few coefficients (9 doubles I think) are all thats required in SH to get back to something pretty close to the real irradiance values.

Map to SH Conversion

There is a directx function available which will do the conversion.

Note in some cases people store SH per vertex, in others it's done per world volume (cubemap) and some people do it per volume but storing the light propagating from the volume rather than the light incident to it. I'm sure there are many other ways of storing the light transport in a scene I can't think of and for many reasons I don't know about. So I think, really, it comes down to; what do you want to get from your irradiance and at what level of detail?

General Links

Good old GPU gems talk about using it.

And here is an excellent document on the topic from Robin Green.

And a personal favourite - Crytek spherical propagation volumes.

A paper from lionhead as well.

  • \$\begingroup\$ Some detail is not required, but I thought it would be nice for people stumbling on this page. Also, I'm not quite phrasing this right, but don't have time to correct it now. Mainly the bit about it being SH vs Cubemap as both are irradiance maps. \$\endgroup\$ – OriginalDaemon Jul 9 '14 at 15:36
  • \$\begingroup\$ You can convert a cubemap to SH by calculating the integral of the cubemap * the SH basis function, for each SH coefficient. In other words, a sum over all the pixels in the cubemap, weighted by solid angle and the SH basis function. \$\endgroup\$ – Nathan Reed Jul 9 '14 at 20:16
  • \$\begingroup\$ Saying that "irradiance maps don't vary a lot, they are low frequency" is only true for irradiance maps built for diffuse BRDFs. Irradiance maps built for more mirror-like BRDFs like Phong or GGX do vary a lot and can be high frequency, depending on the roughness coefficient. That is the whole reason why SH are used for diffuse irradiance maps but cubemaps are used for specular irradiance maps. \$\endgroup\$ – user36169 Apr 27 '17 at 17:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.