Skip to content

Commit 03e500f

Browse files
committed
Clean up #defines
1 parent d635199 commit 03e500f

1 file changed

Lines changed: 75 additions & 73 deletions

File tree

Assets/ScriptableRenderPipeline/ShaderLibrary/AreaLighting.hlsl

Lines changed: 75 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
#ifndef UNITY_AREA_LIGHTING_INCLUDED
22
#define UNITY_AREA_LIGHTING_INCLUDED
33

4-
#define SPHERE_LIGHT_APPROXIMATION
4+
#define APPROXIMATE_POLY_LIGHT_AS_SPHERE_LIGHT
5+
#define APPROXIMATE_SPHERE_LIGHT_NUMERICALLY
56

67
// Not normalized by the factor of 1/TWO_PI.
78
float3 ComputeEdgeFactor(float3 V1, float3 V2)
@@ -40,102 +41,103 @@ float IntegrateEdge(float3 V1, float3 V2)
4041
// N.b.: this function accounts for horizon clipping.
4142
float DiffuseSphereLightIrradiance(float sinSqSigma, float cosOmega)
4243
{
43-
#if 1 // Use a numerical fit for the sphere light approximation found in Mathematica.
44+
#ifdef APPROXIMATE_SPHERE_LIGHT_NUMERICALLY
4445
float x = sinSqSigma;
4546
float y = cosOmega;
4647

47-
// For most of the domain, the absolute error is pretty low, under 0.005.
48-
// You can use the following Mathematica code to reproduce our results:
49-
// t = Flatten[Table[{x, y, f[x, y]}, {x, 0, 0.999999, 0.001}, {y, -0.999999, 0.999999, 0.002}], 1]
50-
// m = NonlinearModelFit[t, x * (y + e) * (0.5 + (y - e) * (a + b * x + c * x^2 + d * x^3)), {a, b, c, d, e}, {x, y}]
51-
return saturate(x * (0.9245867471551246 + y) * (0.5 + (-0.9245867471551246 + y) * (0.5359050373687144 + x * (-1.0054221851257754 + x * (1.8199061187417047 - x * 1.3172081704209504)))));
48+
#if 1
49+
// Use a numerical fit found in Mathematica.
50+
// For most of the domain, the absolute error is fairly low, under 0.005.
51+
// You can use the following Mathematica code to reproduce our results:
52+
// t = Flatten[Table[{x, y, f[x, y]}, {x, 0, 0.999999, 0.001}, {y, -0.999999, 0.999999, 0.002}], 1]
53+
// m = NonlinearModelFit[t, x * (y + e) * (0.5 + (y - e) * (a + b * x + c * x^2 + d * x^3)), {a, b, c, d, e}, {x, y}]
54+
return saturate(x * (0.9245867471551246 + y) * (0.5 + (-0.9245867471551246 + y) * (0.5359050373687144 + x * (-1.0054221851257754 + x * (1.8199061187417047 - x * 1.3172081704209504)))));
55+
#else
56+
// Another fit found with Mathematica. The absolute error is larger (around 0.02 on average), but the function is very smooth.
57+
// You can use the following Mathematica code to reproduce our results:
58+
// t = Flatten[Table[{x, y, f[x, y]}, {x, 0, 0.999999, 0.001}, {y, -0.999999, 0.999999, 0.002}], 1]
59+
// m = NonlinearModelFit[t, 1 - (1 - x)^(a * (y + 1) + b * (y + 1)^2 + c * (y + 1)^3 + d * (y + 1)^4)}, {a, b, c, d}, {x, y}]
60+
float p = saturate(0.14506085844485772 + y * (0.2858221675641456 + y * (0.23405929637528905 + y * (0.20682928702038633 + y * 0.1135312997643852))));
61+
return saturate(1 - pow(1 - x, p));
62+
#endif
5263
#else
53-
float x = sinSqSigma;
54-
float y = cosOmega;
55-
56-
// Another fit found with Mathematica. The error is larger (around 0.02 on average), but the function is very smooth.
57-
// You can use the following Mathematica code to reproduce our results:
58-
// t = Flatten[Table[{x, y, f[x, y]}, {x, 0, 0.999999, 0.001}, {y, -0.999999, 0.999999, 0.002}], 1]
59-
// m = NonlinearModelFit[t, 1 - (1 - x)^(a * (y + 1) + b * (y + 1)^2 + c * (y + 1)^3 + d * (y + 1)^4)}, {a, b, c, d}, {x, y}]
60-
float p = saturate(0.14506085844485772 + y * (0.2858221675641456 + y * (0.23405929637528905 + y * (0.20682928702038633 + y * 0.1135312997643852))));
61-
return saturate(1 - pow(1 - x, p));
62-
#endif
63-
#if 0 // Ref: Area Light Sources for Real-Time Graphics, page 4 (1996).
64-
float sinSqOmega = saturate(1 - cosOmega * cosOmega);
65-
float cosSqSigma = saturate(1 - sinSqSigma);
66-
float sinSqGamma = saturate(cosSqSigma / sinSqOmega);
67-
float cosSqGamma = saturate(1 - sinSqGamma);
64+
#if 0 // Ref: Area Light Sources for Real-Time Graphics, page 4 (1996).
65+
float sinSqOmega = saturate(1 - cosOmega * cosOmega);
66+
float cosSqSigma = saturate(1 - sinSqSigma);
67+
float sinSqGamma = saturate(cosSqSigma / sinSqOmega);
68+
float cosSqGamma = saturate(1 - sinSqGamma);
6869

69-
float sinSigma = sqrt(sinSqSigma);
70-
float sinGamma = sqrt(sinSqGamma);
71-
float cosGamma = sqrt(cosSqGamma);
70+
float sinSigma = sqrt(sinSqSigma);
71+
float sinGamma = sqrt(sinSqGamma);
72+
float cosGamma = sqrt(cosSqGamma);
7273

73-
float sigma = asin(sinSigma);
74-
float omega = acos(cosOmega);
75-
float gamma = asin(sinGamma);
74+
float sigma = asin(sinSigma);
75+
float omega = acos(cosOmega);
76+
float gamma = asin(sinGamma);
7677

77-
if (omega >= HALF_PI + sigma)
78-
{
79-
// Full horizon occlusion (case #4).
80-
return 0;
81-
}
82-
83-
float e = sinSqSigma * cosOmega;
78+
if (omega >= HALF_PI + sigma)
79+
{
80+
// Full horizon occlusion (case #4).
81+
return 0;
82+
}
8483

85-
[branch]
86-
if (omega < HALF_PI - sigma)
87-
{
88-
// No horizon occlusion (case #1).
89-
return e;
90-
}
91-
else
92-
{
93-
float g = (-2 * sqrt(sinSqOmega * cosSqSigma) + sinGamma) * cosGamma + (HALF_PI - gamma);
94-
float h = cosOmega * (cosGamma * sqrt(saturate(sinSqSigma - cosSqGamma)) + sinSqSigma * asin(saturate(cosGamma / sinSigma)));
84+
float e = sinSqSigma * cosOmega;
9585

96-
if (omega < HALF_PI)
86+
[branch]
87+
if (omega < HALF_PI - sigma)
9788
{
98-
// Partial horizon occlusion (case #2).
99-
return saturate(e + INV_PI * (g - h));
89+
// No horizon occlusion (case #1).
90+
return e;
10091
}
10192
else
10293
{
103-
// Partial horizon occlusion (case #3).
104-
return saturate(INV_PI * (g + h));
94+
float g = (-2 * sqrt(sinSqOmega * cosSqSigma) + sinGamma) * cosGamma + (HALF_PI - gamma);
95+
float h = cosOmega * (cosGamma * sqrt(saturate(sinSqSigma - cosSqGamma)) + sinSqSigma * asin(saturate(cosGamma / sinSigma)));
96+
97+
if (omega < HALF_PI)
98+
{
99+
// Partial horizon occlusion (case #2).
100+
return saturate(e + INV_PI * (g - h));
101+
}
102+
else
103+
{
104+
// Partial horizon occlusion (case #3).
105+
return saturate(INV_PI * (g + h));
106+
}
105107
}
106-
}
107-
#else // Ref: Moving Frostbite to Physically Based Rendering, page 47 (2015, optimized).
108-
float cosSqOmega = cosOmega * cosOmega; // y^2
108+
#else // Ref: Moving Frostbite to Physically Based Rendering, page 47 (2015, optimized).
109+
float cosSqOmega = cosOmega * cosOmega; // y^2
109110

110-
[branch]
111-
if (cosSqOmega > sinSqSigma) // (y^2)>x
112-
{
113-
return saturate(sinSqSigma * cosOmega); // Clip[x*y,{0,1}]
114-
}
115-
else
116-
{
117-
float cotSqSigma = rcp(sinSqSigma) - 1; // 1/x-1
118-
float tanSqSigma = rcp(cotSqSigma); // x/(1-x)
119-
float sinSqOmega = 1 - cosSqOmega; // 1-y^2
111+
[branch]
112+
if (cosSqOmega > sinSqSigma) // (y^2)>x
113+
{
114+
return saturate(sinSqSigma * cosOmega); // Clip[x*y,{0,1}]
115+
}
116+
else
117+
{
118+
float cotSqSigma = rcp(sinSqSigma) - 1; // 1/x-1
119+
float tanSqSigma = rcp(cotSqSigma); // x/(1-x)
120+
float sinSqOmega = 1 - cosSqOmega; // 1-y^2
120121

121-
float w = sinSqOmega * tanSqSigma; // (1-y^2)*(x/(1-x))
122-
float x = -cosOmega * rsqrt(w); // -y*Sqrt[(1/x-1)/(1-y^2)]
123-
float y = sqrt(sinSqOmega * tanSqSigma - cosSqOmega); // Sqrt[(1-y^2)*(x/(1-x))-y^2]
124-
float z = y * cotSqSigma; // Sqrt[(1-y^2)*(x/(1-x))-y^2]*(1/x-1)
122+
float w = sinSqOmega * tanSqSigma; // (1-y^2)*(x/(1-x))
123+
float x = -cosOmega * rsqrt(w); // -y*Sqrt[(1/x-1)/(1-y^2)]
124+
float y = sqrt(sinSqOmega * tanSqSigma - cosSqOmega); // Sqrt[(1-y^2)*(x/(1-x))-y^2]
125+
float z = y * cotSqSigma; // Sqrt[(1-y^2)*(x/(1-x))-y^2]*(1/x-1)
125126

126-
float a = cosOmega * acos(x) - z; // y*ArcCos[-y*Sqrt[(1/x-1)/(1-y^2)]]-Sqrt[(1-y^2)*(x/(1-x))-y^2]*(1/x-1)
127-
float b = atan(y); // ArcTan[Sqrt[(1-y^2)*(x/(1-x))-y^2]]
127+
float a = cosOmega * acos(x) - z; // y*ArcCos[-y*Sqrt[(1/x-1)/(1-y^2)]]-Sqrt[(1-y^2)*(x/(1-x))-y^2]*(1/x-1)
128+
float b = atan(y); // ArcTan[Sqrt[(1-y^2)*(x/(1-x))-y^2]]
128129

129-
// Replacing max() with saturate() results in a 12 cycle SGPR forwarding stall on PS4.
130-
return max(INV_PI * (a * sinSqSigma + b), 0); // (a/Pi)*x+(b/Pi)
131-
}
130+
// Replacing max() with saturate() results in a 12 cycle SGPR forwarding stall on PS4.
131+
return max(INV_PI * (a * sinSqSigma + b), 0); // (a/Pi)*x+(b/Pi)
132+
}
133+
#endif
132134
#endif
133135
}
134136

135137
// Expects non-normalized vertex positions.
136138
float PolygonIrradiance(float4x3 L)
137139
{
138-
#ifdef SPHERE_LIGHT_APPROXIMATION
140+
#ifdef APPROXIMATE_POLY_LIGHT_AS_SPHERE_LIGHT
139141
[unroll]
140142
for (uint i = 0; i < 4; i++)
141143
{

0 commit comments

Comments
 (0)