Spherical Harmonics Rotation

Started by
22 comments, last by DarkChris 13 years, 5 months ago
How am I supposed to rotate 3 bands of spherical harmonics (9 coefficients) into tangent space?
Are there any good papers on that topic, or any code already written, since mine won't differ from the conventional way anyway.
Advertisement
You usually don't have to. If you just want to get diffuse lighting, evaluate the polynomial the SH coordinates represent at the normal vector.
I know... But in my case I have to... I have to multiplicate them with other coefficients that are in tangent space (e.g. PRT).
The SH rotation gritty details paper has a good section on how to do this.

Also, look up "Stupid SH Tricks"
Ok, but what kind of Rotation will I need to rotate them into Tangent Space. ZYZ, ZXZ or ZYX (Yaw, Pitch, Roll)?

I guess it's depending on how I calculate alpha, beta and gamma... And how do I calculate them?
The best and most robust implementation of SH rotations I've found has been in the paper "Algorithms for Spherical Harmonic Lighting" by Ian Lisle and Tracy Huang.

-= Dave
Graphics Programmer - Ready At Dawn Studios
I solved it... I just rotated about Theta (Y) and Phi (Z). And now it's working perfectly fine.

Edit: Well. Or not.

Am I right that I don't need the Binormals nor the Tangents for the rotation into the tangent space, when I'm only using unshadowed radiance transfer?

And most importantly how can a scalar product over 2 pairs of 9 coefficients be the same as the integral? Let's just take a look at (1,-1). It's part of the linear band meaning that it describes if the axis it's describing is more positive or negative. Let's just say it's describing the x axis. If we take unshadowed radiance transfer, we need to parameterize the lighting and max(0, cos(theta)). Since the cosine is neither more right nor more left, the final coefficient will be 0. In fact, it will be non-zero on all (L,0) coefficients. It basically just says that it always blocks off all incident light the same independent of the x-axis. So if the actual incident light is stronger from the right, it will result in an coefficient being non-zero. Now if we multiply those together (since the integral is the same as the scalar product), we get zero since x * 0 = 0. But that's just not correct. There is more incident light from the right, than from the left.

[Edited by - DarkChris on November 16, 2010 12:02:54 PM]
Quote:Original post by DarkChris
And most importantly how can a scalar product over 2 pairs of 9 coefficients be the same as the integral?

The integral disappears because of the orthonormal nature of the basis. As you may know from linear algebra the dot product of two vector's in an orthonormal basis are 1 when they are the same and 0 when they are not. In a functional basis the integral of the same basis is 1 when they are the same and 0 when they are different. A functional basis has infinite components and an integral is essentially a dot product. More generally, in a functional basis we call it the inner product.

Let's start off with the integral of two functions parameterized over the hemisphere (theta and phi).


Then we project both functions onto a spherical harmonic basis Y and reconstruct using its coefficients.


Now we have an alternate version of A and B so we can substitute them back into the original integral.



Because of the linearality of integrals we can pull the summation outside of the integral and we can pull the constant coefficient multiplies out as well.


Now the magic of orthogonality means that if Y_{l,m} != Y_{l,m} we get 0 when we integrate Y against itself. That means if l and m are not equal for both A and B we get 0. This simplifies it down to the integral.


Also, because because the basis are always the same we simplify the original equation down to



[Edited by - David Neubelt on November 16, 2010 4:07:27 PM]
Graphics Programmer - Ready At Dawn Studios
Quote:Original post by DarkChris
Let's just take a look at (1,-1). It's part of the linear band meaning that it describes if the axis it's describing is more positive or negative. Let's just say it's describing the x axis. If we take unshadowed radiance transfer, we need to parameterize the lighting and max(0, cos(theta)). Since the cosine is neither more right nor more left, the final coefficient will be 0.


No, that's not correct. Cosine has no dependence on its azimuthal angle which means it has the same coefficient no matter the angle of phi. The coefficient for 1,-1 will be same coefficient as it is for 1,0 (because phi doesn't matter!)

The first 9 coefficients of max(cosine(\theta), 0) are the following,

// constant band
A_{0, 0} = 3.141593f

// linear band
A_{1,-1} = 2.095395f
A_{1, 0} = 2.095395f
A_{1, 1} = 2.095395f

// quadratic band
A_{2,-2} = 0.785398f
A_{2,-1} = 0.785398f
A_{2, 0} = 0.785398f
A_{2, 1} = 0.785398f
A_{2, 2} = 0.785398f

EDIT: The above is wrong and I will leave for reference.
* You do want to take those 9 coefficients and multiply them by your 9 SH coeffients.
* What I was wrong about was saying that the coefficients would be the same for a clamped cos but in fact if the coefficients had represented clamped cos(\theta) then they would be 0 for any band where m != 0 but these coefficients do not reflect a clamped cos(\theta) read my post further down for details on what the coefficients reflect.

[Edited by - David Neubelt on November 17, 2010 3:18:10 AM]
Graphics Programmer - Ready At Dawn Studios
Quote:Original post by DarkChris
Am I right that I don't need the Binormals nor the Tangents for the rotation into the tangent space, when I'm only using unshadowed radiance transfer?


I'm not quite sure how your rendering is setup but when I implemented PRT I never needed to rotate my lighting. The visibility and indirect lighting is implemented by simply scaling the incoming lighting.

Graphics Programmer - Ready At Dawn Studios

This topic is closed to new replies.

Advertisement