123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211 |
- #ifndef UNITY_SPHERICAL_HARMONICS_INCLUDED
- #define UNITY_SPHERICAL_HARMONICS_INCLUDED
-
- #ifdef UNITY_COLORSPACE_GAMMA
- #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl"
- #endif
-
- // SH Basis coefs
- #define kSHBasis0 0.28209479177387814347f // {0, 0} : 1/2 * sqrt(1/Pi)
- #define kSHBasis1 0.48860251190291992159f // {1, 0} : 1/2 * sqrt(3/Pi)
- #define kSHBasis2 1.09254843059207907054f // {2,-2} : 1/2 * sqrt(15/Pi)
- #define kSHBasis3 0.31539156525252000603f // {2, 0} : 1/4 * sqrt(5/Pi)
- #define kSHBasis4 0.54627421529603953527f // {2, 2} : 1/4 * sqrt(15/Pi)
-
- static const float kSHBasisCoef[] = { kSHBasis0, -kSHBasis1, kSHBasis1, -kSHBasis1, kSHBasis2, -kSHBasis2, kSHBasis3, -kSHBasis2, kSHBasis4 };
-
- // Clamped cosine convolution coefs (pre-divided by PI)
- // See https://seblagarde.wordpress.com/2012/01/08/pi-or-not-to-pi-in-game-lighting-equation/
- #define kClampedCosine0 (1.0f)
- #define kClampedCosine1 (2.0f / 3.0f)
- #define kClampedCosine2 (1.0f / 4.0f)
-
- static const float kClampedCosineCoefs[] = { kClampedCosine0, kClampedCosine1, kClampedCosine1, kClampedCosine1, kClampedCosine2, kClampedCosine2, kClampedCosine2, kClampedCosine2, kClampedCosine2 };
-
- // Ref: "Efficient Evaluation of Irradiance Environment Maps" from ShaderX 2
- real3 SHEvalLinearL0L1(real3 N, real4 shAr, real4 shAg, real4 shAb)
- {
- real4 vA = real4(N, 1.0);
-
- real3 x1;
- // Linear (L1) + constant (L0) polynomial terms
- x1.r = dot(shAr, vA);
- x1.g = dot(shAg, vA);
- x1.b = dot(shAb, vA);
-
- return x1;
- }
-
- real3 SHEvalLinearL1(real3 N, real3 shAr, real3 shAg, real3 shAb)
- {
- real3 x1;
- x1.r = dot(shAr, N);
- x1.g = dot(shAg, N);
- x1.b = dot(shAb, N);
-
- return x1;
- }
-
- real3 SHEvalLinearL2(real3 N, real4 shBr, real4 shBg, real4 shBb, real4 shC)
- {
- real3 x2;
- // 4 of the quadratic (L2) polynomials
- real4 vB = N.xyzz * N.yzzx;
- x2.r = dot(shBr, vB);
- x2.g = dot(shBg, vB);
- x2.b = dot(shBb, vB);
-
- // Final (5th) quadratic (L2) polynomial
- real vC = N.x * N.x - N.y * N.y;
- real3 x3 = shC.rgb * vC;
-
- return x2 + x3;
- }
-
- #if !HALF_IS_FLOAT
- half3 SampleSH9(half4 SHCoefficients[7], half3 N)
- {
- half4 shAr = SHCoefficients[0];
- half4 shAg = SHCoefficients[1];
- half4 shAb = SHCoefficients[2];
- half4 shBr = SHCoefficients[3];
- half4 shBg = SHCoefficients[4];
- half4 shBb = SHCoefficients[5];
- half4 shCr = SHCoefficients[6];
-
- // Linear + constant polynomial terms
- half3 res = SHEvalLinearL0L1(N, shAr, shAg, shAb);
-
- // Quadratic polynomials
- res += SHEvalLinearL2(N, shBr, shBg, shBb, shCr);
-
- #ifdef UNITY_COLORSPACE_GAMMA
- res = LinearToSRGB(res);
- #endif
-
- return res;
- }
-
- half3 SampleSH4_L1(half4 SHCoefficients[3], half3 N)
- {
- half4 shAr = SHCoefficients[0];
- half4 shAg = SHCoefficients[1];
- half4 shAb = SHCoefficients[2];
-
- // Linear + constant polynomial terms
- half3 res = SHEvalLinearL1(N, shAr.xyz, shAg.xyz, shAb.xyz);
-
- #ifdef UNITY_COLORSPACE_GAMMA
- res = LinearToSRGB(res);
- #endif
-
- return res;
- }
- #endif
-
- float3 SampleSH9(float4 SHCoefficients[7], float3 N)
- {
- 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];
-
- // Linear + constant polynomial terms
- float3 res = SHEvalLinearL0L1(N, shAr, shAg, shAb);
-
- // Quadratic polynomials
- res += SHEvalLinearL2(N, shBr, shBg, shBb, shCr);
-
- #ifdef UNITY_COLORSPACE_GAMMA
- res = LinearToSRGB(res);
- #endif
-
- return res;
- }
-
- float3 SampleSH9(StructuredBuffer<float4> data, float3 N)
- {
- real4 SHCoefficients[7];
- SHCoefficients[0] = data[0];
- SHCoefficients[1] = data[1];
- SHCoefficients[2] = data[2];
- SHCoefficients[3] = data[3];
- SHCoefficients[4] = data[4];
- SHCoefficients[5] = data[5];
- SHCoefficients[6] = data[6];
-
- return SampleSH9(SHCoefficients, N);
- }
-
- float3 SampleSH4_L1(float4 SHCoefficients[3], float3 N)
- {
- float4 shAr = SHCoefficients[0];
- float4 shAg = SHCoefficients[1];
- float4 shAb = SHCoefficients[2];
-
- // Linear + constant polynomial terms
- float3 res = SHEvalLinearL1(N, (float3)shAr, (float3)shAg, (float3)shAb);
-
- #ifdef UNITY_COLORSPACE_GAMMA
- res = LinearToSRGB(res);
- #endif
-
- return res;
- }
-
- void GetCornetteShanksPhaseFunction(out float3 zh, float anisotropy)
- {
- float g = anisotropy;
-
- zh.x = 0.282095f;
- zh.y = 0.293162f * g * (4.0f + (g * g)) / (2.0f + (g * g));
- zh.z = (0.126157f + 1.44179f * (g * g) + 0.324403f * (g * g) * (g * g)) / (2.0f + (g * g));
- }
-
- void ConvolveZonal(inout float sh[27], float3 zh)
- {
- for (int l = 0; l <= 2; l++)
- {
- float n = sqrt((4.0f * PI) / (2 * l + 1));
- float k = zh[l];
- float p = n * k;
-
- for (int m = -l; m <= l; m++)
- {
- int i = l * (l + 1) + m;
-
- for (int c = 0; c < 3; c++)
- {
- sh[c * 9 + i] = sh[c * 9 + i] * p;
- }
- }
- }
- }
-
- // Packs coefficients so that we can use Peter-Pike Sloan's shader code.
- // The function does not perform premultiplication with coefficients of SH basis functions, caller need to do it
- // See SetSHEMapConstants() in "Stupid Spherical Harmonics Tricks".
- // Constant + linear
- void PackSH(RWStructuredBuffer<float4> buffer, float sh[27])
- {
- int c = 0;
- for (c = 0; c < 3; c++)
-
- {
- buffer[c] = float4(sh[c * 9 + 3], sh[c * 9 + 1], sh[c * 9 + 2], sh[c * 9 + 0] - sh[c * 9 + 6]);
- }
-
- // Quadratic (4/5)
- for (c = 0; c < 3; c++)
- {
- buffer[3 + c] = float4(sh[c * 9 + 4], sh[c * 9 + 5], sh[c * 9 + 6] * 3.0f, sh[c * 9 + 7]);
- }
-
- // Quadratic (5)
- buffer[6] = float4(sh[0 * 9 + 8], sh[1 * 9 + 8], sh[2 * 9 + 8], 1.0f);
- }
-
- #endif // UNITY_SPHERICAL_HARMONICS_INCLUDED
|