PBRSpotLight.glsl 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344
  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,
  9. in vec3 theNormal,
  10. in vec3 theView,
  11. in vec3 thePoint,
  12. in bool theIsFront)
  13. {
  14. vec3 aLight = occLight_Position (theId) - thePoint;
  15. float aDist = length (aLight);
  16. float aRange = occLight_Range (theId);
  17. float anAtten = occPointLightAttenuation (aDist, aRange);
  18. if (anAtten <= 0.0) return;
  19. aLight /= aDist;
  20. vec3 aSpotDir = occLight_SpotDirection (theId);
  21. // light cone
  22. float aCosA = dot (aSpotDir, -aLight);
  23. float aRelativeAngle = 2.0 * acos(aCosA) / occLight_SpotCutOff(theId);
  24. if (aCosA >= 1.0 || aRelativeAngle > 1.0)
  25. {
  26. return;
  27. }
  28. float anExponent = occLight_SpotExponent (theId);
  29. if ((1.0 - aRelativeAngle) <= anExponent)
  30. {
  31. float anAngularAttenuationOffset = cos(0.5 * occLight_SpotCutOff(theId));
  32. float anAngularAttenuationScale = 1.0 / max(0.001, cos(0.5 * occLight_SpotCutOff(theId) * (1.0 - anExponent)) - anAngularAttenuationOffset);
  33. anAngularAttenuationOffset *= -anAngularAttenuationScale;
  34. float anAngularAttenuantion = clamp(aCosA * anAngularAttenuationScale + anAngularAttenuationOffset, 0.0, 1.0);
  35. anAtten *= anAngularAttenuantion * anAngularAttenuantion;
  36. }
  37. theNormal = theIsFront ? theNormal : -theNormal;
  38. DirectLighting += occPBRIllumination (theView, aLight, theNormal,
  39. BaseColor, Metallic, Roughness, IOR,
  40. occLight_Specular(theId),
  41. occLight_Intensity(theId) * anAtten);
  42. }