1
$\begingroup$

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

$\endgroup$

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Browse other questions tagged or ask your own question.