Original Post
I've been looking at SH in Actual Games - by Tom Forsyth and I have no idea whther I have the coefficients the right way round... i.e. 1,x,y,z,xz,yx,xy,3z^2-1,x^2-y^2
obv there is more than one typo because in another place Forsyth puts them 1,x,y,z,xz,yx,xy,x^2-y^2,1-3z^2 which is frustrating
A stanford paper and source put the coeffs 1,y,x,z,xy,yx,xz,3z^2-1,x^2-y^2 so I am totally lost
I want to use 2nd order spherical harmonics with 9 coefficients, I dunno what I am doing wrong. I also think I have my constants/weights wrong too :( i.e. 0.282095 and so on
The only thing I am positive I got right is the differential solid angle
I'm planning to convert cubemaps into SH but for now I have a simple test app which simulates as if there is only 1 pixel per face... (6 colors) red,green,blue,yellow, white and black corresponding to the "dir" parameter (i.e. red is front/z+)
I struggle with the math and just checking the differential solid angle took me 2 days so I would much appreciate if you could DUMBDOWN the topic for me or show me some piece of code that I could use the constants from
Right here is my little code dir basically means 0=forward, 1= right, back,left, up and down
float u,v,x,y,z,domega,c,fwt;
u = 0; /* u ranges from -1 to 1 */
v = 0; /* v ranges from -1 to 1 */
fwt = u*u+v*v+1.f;
c = sqrt(fwt);
if (dir==0) {
x=u;
y=v;
z=1.f;
}
else if (dir==1) {
x=1.f;
y=v;
z=-u;
}
else if (dir==2) {
x=-u;
y=v;
z=-1.f;
}
else if (dir==3) {
x=-1.f;
y=v;
z=u;
}
else if (dir==4) {
x=u;
y=1.f;
z=v;
}
else if (dir==5) {
x=-u;
y=-1.f;
z=-v;
}
x /= c;
y /= c;
z /= c;
c = 1.f/(fwt*c);
fwtSum += c;
domega = c;
c = 0.282095*domega;
coeff[0] += col.X*c;
coeff[1] += col.Y*c;
coeff[2] += col.Z*c;
c = 0.488603*domega;
coeff[3] += col.X*c*x;
coeff[4] += col.Y*c*x;
coeff[5] += col.Z*c*x;
coeff[6] += col.X*c*y;
coeff[7] += col.Y*c*y;
coeff[8] += col.Z*c*y;
coeff[9] += col.X*c*z;
coeff[10] += col.Y*c*z;
coeff[11] += col.Z*c*z;
c = 1.092548*domega;
coeff[12] += col.X*c*x*z;
coeff[13] += col.Y*c*x*z;
coeff[14] += col.Z*c*x*z;
coeff[15] += col.X*c*y*z;
coeff[16] += col.Y*c*y*z;
coeff[17] += col.Z*c*y*z;
coeff[18] += col.X*c*x*y;
coeff[19] += col.Y*c*x*y;
coeff[20] += col.Z*c*x*y;
c = 1.092548*domega*(3.f*z*z-1.f);
coeff[21] += col.X*c;
coeff[22] += col.Y*c;
coeff[23] += col.Z*c;
c = 0.546274*domega*(x*x-y*y);
coeff[24] += col.X*c;
coeff[25] += col.Y*c;
coeff[26] += col.Z*c;
after all sides are processed I scale the entire harmonic by 4.f*core::PI/(fwtSum*6.f)
obv there is more than one typo because in another place Forsyth puts them 1,x,y,z,xz,yx,xy,x^2-y^2,1-3z^2 which is frustrating
A stanford paper and source put the coeffs 1,y,x,z,xy,yx,xz,3z^2-1,x^2-y^2 so I am totally lost
I want to use 2nd order spherical harmonics with 9 coefficients, I dunno what I am doing wrong. I also think I have my constants/weights wrong too :( i.e. 0.282095 and so on
The only thing I am positive I got right is the differential solid angle
I'm planning to convert cubemaps into SH but for now I have a simple test app which simulates as if there is only 1 pixel per face... (6 colors) red,green,blue,yellow, white and black corresponding to the "dir" parameter (i.e. red is front/z+)
I struggle with the math and just checking the differential solid angle took me 2 days so I would much appreciate if you could DUMBDOWN the topic for me or show me some piece of code that I could use the constants from
Right here is my little code dir basically means 0=forward, 1= right, back,left, up and down
float u,v,x,y,z,domega,c,fwt;
u = 0; /* u ranges from -1 to 1 */
v = 0; /* v ranges from -1 to 1 */
fwt = u*u+v*v+1.f;
c = sqrt(fwt);
if (dir==0) {
x=u;
y=v;
z=1.f;
}
else if (dir==1) {
x=1.f;
y=v;
z=-u;
}
else if (dir==2) {
x=-u;
y=v;
z=-1.f;
}
else if (dir==3) {
x=-1.f;
y=v;
z=u;
}
else if (dir==4) {
x=u;
y=1.f;
z=v;
}
else if (dir==5) {
x=-u;
y=-1.f;
z=-v;
}
x /= c;
y /= c;
z /= c;
c = 1.f/(fwt*c);
fwtSum += c;
domega = c;
c = 0.282095*domega;
coeff[0] += col.X*c;
coeff[1] += col.Y*c;
coeff[2] += col.Z*c;
c = 0.488603*domega;
coeff[3] += col.X*c*x;
coeff[4] += col.Y*c*x;
coeff[5] += col.Z*c*x;
coeff[6] += col.X*c*y;
coeff[7] += col.Y*c*y;
coeff[8] += col.Z*c*y;
coeff[9] += col.X*c*z;
coeff[10] += col.Y*c*z;
coeff[11] += col.Z*c*z;
c = 1.092548*domega;
coeff[12] += col.X*c*x*z;
coeff[13] += col.Y*c*x*z;
coeff[14] += col.Z*c*x*z;
coeff[15] += col.X*c*y*z;
coeff[16] += col.Y*c*y*z;
coeff[17] += col.Z*c*y*z;
coeff[18] += col.X*c*x*y;
coeff[19] += col.Y*c*x*y;
coeff[20] += col.Z*c*x*y;
c = 1.092548*domega*(3.f*z*z-1.f);
coeff[21] += col.X*c;
coeff[22] += col.Y*c;
coeff[23] += col.Z*c;
c = 0.546274*domega*(x*x-y*y);
coeff[24] += col.X*c;
coeff[25] += col.Y*c;
coeff[26] += col.Z*c;
after all sides are processed I scale the entire harmonic by 4.f*core::PI/(fwtSum*6.f)