# Questions about caculate the highlight direction from spherical harmonics functions.

Discussion in 'Universal Render Pipeline' started by wechat_os_Qy0_Jl1Bu_ReX4uviBciQe8d4, Apr 14, 2021.

1. ### wechat_os_Qy0_Jl1Bu_ReX4uviBciQe8d4

Joined:
Sep 9, 2018
Posts:
1
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

unityunity