|
|
|
|
|
|
|
|
|
|
// Non physically based hack to limit light influence to attenuationRadius. |
|
|
|
// SmoothInfluenceAttenuation must be use, InfluenceAttenuation is just for optimization with SmoothQuadraticDistanceAttenuation |
|
|
|
real InfluenceAttenuation(real distSquare, real invSqrAttenuationRadius) |
|
|
|
real InfluenceAttenuation(real distSquare, real rangeAttenuationScale, real rangeAttenuationBias) |
|
|
|
real factor = distSquare * invSqrAttenuationRadius; |
|
|
|
return saturate(1.0 - factor * factor); |
|
|
|
// Apply the saturate here as we can have negative number |
|
|
|
real factor = saturate(distSquare * rangeAttenuationScale + rangeAttenuationBias); |
|
|
|
return 1.0 - factor * factor; |
|
|
|
real SmoothInfluenceAttenuation(real distSquare, real invSqrAttenuationRadius) |
|
|
|
real SmoothInfluenceAttenuation(real distSquare, real rangeAttenuationScale, real rangeAttenuationBias) |
|
|
|
real smoothFactor = InfluenceAttenuation(distSquare, invSqrAttenuationRadius); |
|
|
|
real smoothFactor = InfluenceAttenuation(distSquare, rangeAttenuationScale, rangeAttenuationBias); |
|
|
|
return Sq(smoothFactor); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
real SmoothQuadraticDistanceAttenuation(real distSquare, real distRcp, real invSqrAttenuationRadius) |
|
|
|
real SmoothQuadraticDistanceAttenuation(real distSquare, real distRcp, real rangeAttenuationScale, real rangeAttenuationBias) |
|
|
|
attenuation *= InfluenceAttenuation(distSquare, invSqrAttenuationRadius); |
|
|
|
attenuation *= InfluenceAttenuation(distSquare, rangeAttenuationScale, rangeAttenuationBias); |
|
|
|
real SmoothQuadraticDistanceAttenuation(real3 unL, real invSqrAttenuationRadius) |
|
|
|
real SmoothQuadraticDistanceAttenuation(real3 unL, real rangeAttenuationScale, real rangeAttenuationBias) |
|
|
|
return SmoothQuadraticDistanceAttenuation(distSquare, distRcp, invSqrAttenuationRadius); |
|
|
|
return SmoothQuadraticDistanceAttenuation(distSquare, distRcp, rangeAttenuationScale, rangeAttenuationBias); |
|
|
|
} |
|
|
|
|
|
|
|
real AngleAttenuation(real cosFwd, real lightAngleScale, real lightAngleOffset) |
|
|
|
|
|
|
|
|
|
|
// Combines SmoothQuadraticDistanceAttenuation() and SmoothAngleAttenuation() in an efficient manner. |
|
|
|
// distances = {d, d^2, 1/d, d_proj}, where d_proj = dot(lightToSample, lightData.forward). |
|
|
|
real SmoothPunctualLightAttenuation(real4 distances, real invSqrAttenuationRadius, |
|
|
|
real SmoothPunctualLightAttenuation(real4 distances, real rangeAttenuationScale, real rangeAttenuationBias, |
|
|
|
real lightAngleScale, real lightAngleOffset) |
|
|
|
{ |
|
|
|
real distSq = distances.y; |
|
|
|
|
|
|
|
|
|
|
real attenuation = min(distRcp, 1.0 / PUNCTUAL_LIGHT_THRESHOLD); |
|
|
|
attenuation *= InfluenceAttenuation(distSq, invSqrAttenuationRadius); |
|
|
|
attenuation *= AngleAttenuation(cosFwd, lightAngleScale, lightAngleOffset); |
|
|
|
attenuation *= InfluenceAttenuation(distSq, rangeAttenuationScale, rangeAttenuationBias); |
|
|
|
attenuation *= AngleAttenuation(cosFwd, lightAngleScale, lightAngleOffset); |
|
|
|
|
|
|
|
return Sq(attenuation); |
|
|
|
} |
|
|
|
|
|
|
// The transformation is performed along the major axis of the ellipsoid (corresponding to 'r1'). |
|
|
|
// Both the ellipsoid (e.i. 'axis') and 'unL' should be in the same coordinate system. |
|
|
|
// 'unL' should be computed from the center of the ellipsoid. |
|
|
|
real EllipsoidalDistanceAttenuation(real3 unL, real invSqRadius, |
|
|
|
real EllipsoidalDistanceAttenuation(real3 unL, real rangeAttenuationScale, real rangeAttenuationBias, |
|
|
|
real3 axis, real invAspectRatio) |
|
|
|
{ |
|
|
|
// Project the unnormalized light vector onto the axis. |
|
|
|
|
|
|
unL -= diff * axis; |
|
|
|
|
|
|
|
real sqDist = dot(unL, unL); |
|
|
|
return SmoothInfluenceAttenuation(sqDist, invSqRadius); |
|
|
|
return SmoothInfluenceAttenuation(sqDist, rangeAttenuationScale, rangeAttenuationBias); |
|
|
|
} |
|
|
|
|
|
|
|
// Applies SmoothInfluenceAttenuation() using the axis-aligned ellipsoid of the given dimensions. |
|
|
|
|
|
|
unL *= invHalfDim; |
|
|
|
|
|
|
|
real sqDist = dot(unL, unL); |
|
|
|
return SmoothInfluenceAttenuation(sqDist, 1.0); |
|
|
|
return SmoothInfluenceAttenuation(sqDist, 1.0, 0.0); |
|
|
|
} |
|
|
|
|
|
|
|
// Applies SmoothInfluenceAttenuation() after mapping the axis-aligned box to a sphere. |
|
|
|
|
|
|
if (Max3(abs(unL.x), abs(unL.y), abs(unL.z)) > 1.0) return 0.0; |
|
|
|
|
|
|
|
real sqDist = ComputeCubeToSphereMapSqMagnitude(unL); |
|
|
|
return SmoothInfluenceAttenuation(sqDist, 1.0); |
|
|
|
return SmoothInfluenceAttenuation(sqDist, 1.0, 0.0); |
|
|
|
} |
|
|
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
|
|