|
|
|
|
|
|
{ |
|
|
|
float irradiance; |
|
|
|
|
|
|
|
float sinSqOmega = saturate(1 - cosOmega * cosOmega); |
|
|
|
float sinSqOmega = saturate(1 - cosOmega * cosOmega); |
|
|
|
float cosSqSigma = saturate(1 - sinSqSigma); |
|
|
|
float sinSqGamma = saturate(cosSqSigma / sinSqOmega); |
|
|
|
float cosSqGamma = saturate(1 - sinSqGamma); |
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
#else // Ref: Moving Frostbite to Physically Based Rendering, page 47 (2015). |
|
|
|
float cosSqOmega = cosOmega * cosOmega; |
|
|
|
|
|
|
|
if (cosOmega * cosOmega > sinSqSigma) |
|
|
|
if (cosSqOmega > sinSqSigma) |
|
|
|
float a = 1 / sinSqSigma - 1; |
|
|
|
float w = rsqrt(a); |
|
|
|
float x = sqrt(a); |
|
|
|
float y = -x * cosOmega * rsqrt(sinSqOmega); |
|
|
|
float z = sqrt(sinSqOmega * (1 - y * y)); |
|
|
|
float cotanOmega = cosOmega * rsqrt(1 - cosSqOmega); |
|
|
|
irradiance = INV_PI * ((cosOmega * acos(y) - x * z) * sinSqSigma + atan(z * w)); |
|
|
|
float x = rcp(sinSqSigma) - 1; |
|
|
|
float y = -cotanOmega * sqrt(x); |
|
|
|
float z = sqrt(1 - cosSqOmega * rcp(sinSqSigma)); |
|
|
|
|
|
|
|
irradiance = INV_PI * ((cosOmega * acos(y) - z * sqrt(x)) * sinSqSigma + atan(z * rsqrt(x))); |
|
|
|
} |
|
|
|
#endif |
|
|
|
return max(irradiance, 0); |
|
|
|