- Home /
,Questions about caculate the highlight direction from spherical harmonics functions.
,Recently I‘m working on a Precomputed GI Project
I'm trying to use a technique called AHD, Amibent Highlight Direction, rendering my project; I use Unity and my target platform is Android.
First: Unity SH is the result of Encoded and Scaled, I want to get the original SH I'm trying try to decode it, but there are several problems with the sixth coefficient; I found some documents that said unity moved the constant part of L6(band l = 2,order m = 0) to the L0(band l = 0, order m = 0), is that true? If that's right, how can I get the right original SH?
There are some trying of myself, I have tried to calculate the constant part and recalculate the L0 and L6, but it seem not to be correct, in fact, I don't know how to verify it.
#define k01 0.2820947918 // sqrt( 1/PI)/2
#define k02 0.4886025119 // sqrt( 3/PI)/2
#define k03 1.0925484306 // sqrt( 15/PI)/2
#define k04 0.3153915652 // sqrt( 5/PI)/4
#define k05 0.5462742153 // sqrt( 15/PI)/4
float3 SampleRawSH9(float4 SHCoefficients[7], float3 N) {
float3 n = N.zxy;
float4 shAr = SHCoefficients[0];
float4 shAg = SHCoefficients[1];
float4 shAb = SHCoefficients[2];
float4 shBr = SHCoefficients[3];
float4 shBg = SHCoefficients[4];
float4 shBb = SHCoefficients[5];
float4 shCr = SHCoefficients[6];
//band0
//l0 + l6 constant part
float3 L0 = float3(shAr.w, shAg.w, shAb.w);
float3 L6c = -float3(shBr.z, shBg.z, shBb.z)* k04/4.;
L6c = 0;
L0 = (L0 - L6c) / k01;
//band1
//m=-1
float3 L1 = float3(shAr.y * n.y, shAg.y * n.y, shAb.y * n.y);
L1 = L1 * 1.5 / (-k02);
//m=0
float3 L2 = float3(shAr.z * n.z, shAg.z * n.z, shAb.z * n.z);
L2 = L2 * 1.5 / (k02);
//m=1
float3 L3 = float3(shAr.x * n.x, shAg.x * n.x, shAb.x * n.x);
L3 = L3 * 1.5 / (-k02);
//band2
//m=-2
float3 L4 = float3(shBr.x * n.x * n.y, shBg.x * n.x * n.y, shBb.x * n.x * n.y);
L4 = L4 * 4. / (k03);
//m=-1
float3 L5 = float3(shBr.y * n.y * n.z, shBg.y * n.y * n.z, shBb.y * n.y * n.z);
L5 = L5 * 4. / (-k03);
//m=0
float3 L6cos = float3(shBr.z * n.z * n.z, shBg.z * n.z * n.z, shBb.z * n.z * n.z);
float3 L6 = L6cos * 4. / (k04 * 3.0) + L6c * 4. / (k04);
//m=1
float3 L7 = float3(shBr.w * n.x * n.z, shBg.w * n.x * n.z, shBb.w * n.x * n.z);
L7 = L7 * 4. / (-k03);
//m=2
float3 L8 = shCr.rgb * (n.x * n.x - n.y * n.y);
L8 = L8 * 4. / (k05);
return L0 + L1 + L2 + L3 + L4 + L5 + L6 + L7 + L8;
}
Second: I try to rebuild my AHD from SH. I'm confused with amibentColor part. Does it contain the part of Directional Light Diffuse term? The results look strange; Same as the previous one, I still can't verify the correctness of my calculation
void SampleRawSHAHD(float3 normalWS, out float highLightFactor, out float3 highLightDir, out float3 highLightColor, out float3 ambientColor) {
real4 SHCoefficients[7];
SHCoefficients[0] = unity_SHAr;
SHCoefficients[1] = unity_SHAg;
SHCoefficients[2] = unity_SHAb;
SHCoefficients[3] = unity_SHBr;
SHCoefficients[4] = unity_SHBg;
SHCoefficients[5] = unity_SHBb;
SHCoefficients[6] = unity_SHC;
highLightDir = SampleRawSHDir(SHCoefficients, normalWS);
highLightFactor = length(highLightDir) * PI * 16 / 17;
highLightDir = normalize(highLightDir);
highLightColor = highLightFactor * SampleRawSH(highLightDir) * 867. / (316. * PI);
ambientColor = (SampleRawSH(0) - highLightColor * 8. * sqrt(PI) / 17.) * sqrt(PI) / 2.;
}
I really appreciate someone who can give me some guidance!
My reference:
https://www.ppsloan.org/publications/StupidSH36.pdf http://graphics.stanford.edu/papers/envmap/envmap.pdf
Your answer
![](https://koobas.hobune.stream/wayback/20220613032229im_/https://answers.unity.com/themes/thub/images/avi.jpg)