1 //! Function computes contribution of spotlight source
2 //! into global variable DirectLighting (PBR shading).
3 //! @param theId light source index
4 //! @param theNormal surface normal
5 //! @param theView view direction
6 //! @param thePoint 3D position (world space)
7 //! @param theIsFront front/back face flag
8 void occSpotLight (in int theId,
14 vec3 aLight = occLight_Position (theId) - thePoint;
16 float aDist = length (aLight);
17 float aRange = occLight_Range (theId);
18 float anAtten = occPointLightAttenuation (aDist, aRange);
19 if (anAtten <= 0.0) return;
22 vec3 aSpotDir = occLight_SpotDirection (theId);
24 float aCosA = dot (aSpotDir, -aLight);
25 float aRelativeAngle = 2.0 * acos(aCosA) / occLight_SpotCutOff(theId);
26 if (aCosA >= 1.0 || aRelativeAngle > 1.0)
30 float anExponent = occLight_SpotExponent (theId);
31 if ((1.0 - aRelativeAngle) <= anExponent)
33 float anAngularAttenuationOffset = cos(0.5 * occLight_SpotCutOff(theId));
34 float anAngularAttenuationScale = 1.0 / max(0.001, cos(0.5 * occLight_SpotCutOff(theId) * (1.0 - anExponent)) - anAngularAttenuationOffset);
35 anAngularAttenuationOffset *= -anAngularAttenuationScale;
36 float anAngularAttenuantion = clamp(aCosA * anAngularAttenuationScale + anAngularAttenuationOffset, 0.0, 1.0);
37 anAtten *= anAngularAttenuantion * anAngularAttenuantion;
39 theNormal = theIsFront ? theNormal : -theNormal;
40 DirectLighting += occPBRIllumination (theView, aLight, theNormal,
41 BaseColor, Metallic, Roughness, IOR,
42 occLight_Specular(theId),
43 occLight_Intensity(theId) * anAtten);