attenuation.chunk 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. // base
  2. float SmoothDistAtt2 (float distSqr, float invSqrAttRadius) {
  3. float factor = distSqr * invSqrAttRadius; // ^2
  4. float factor2 = factor * factor; // ^4
  5. float factor3 = factor2 * factor2; // ^8
  6. float smoothFactor = clamp(1.0 - factor3 * factor3, 0.0, 1.0);
  7. return smoothFactor * smoothFactor;
  8. }
  9. float SmoothDistAtt (float distSqr, float invSqrAttRadius) {
  10. float factor = distSqr * invSqrAttRadius;
  11. float smoothFactor = clamp(1.0 - factor * factor, 0.0, 1.0);
  12. return smoothFactor * smoothFactor;
  13. }
  14. float GetDistAtt (float distSqr, float invSqrAttRadius) {
  15. float attenuation = 1.0 / max(distSqr, 0.01*0.01);
  16. attenuation *= SmoothDistAtt(distSqr , invSqrAttRadius);
  17. return attenuation;
  18. }
  19. float GetAngleAtt (vec3 L, vec3 litDir, float litAngleScale, float litAngleOffset) {
  20. float cd = dot(litDir, L);
  21. float attenuation = clamp(cd * litAngleScale + litAngleOffset, 0.0, 1.0);
  22. return (attenuation * attenuation);
  23. }
  24. float GetOutOfRange (vec3 worldPos, vec3 lightPos, vec3 lookAt, vec3 right, vec3 BoundingHalfSizeVS) {
  25. vec3 v = vec3(0.0);
  26. vec3 up = cross(right, lookAt);
  27. worldPos -= lightPos;
  28. v.x = dot(worldPos, right);
  29. v.y = dot(worldPos, up);
  30. v.z = dot(worldPos, lookAt);
  31. vec3 result = step(abs(v), BoundingHalfSizeVS);
  32. return result.x * result.y * result.z;
  33. }
  34. // advanced
  35. float CalculateDistanceAttenuation(float distToLightSqr, float lightRadius, float lightRange, float lightType)
  36. {
  37. // physical attenuation
  38. float attRadiusSqrInv = 1.0 / max(lightRange, 0.01);
  39. attRadiusSqrInv *= attRadiusSqrInv;
  40. // artical soft edge fading
  41. float litRadiusSqr = lightRadius * lightRadius;
  42. float edgeAttenuation = (IS_POINT_LIGHT(lightType) || IS_RANGED_DIRECTIONAL_LIGHT(lightType)) ? 1.0 : litRadiusSqr / max(litRadiusSqr, distToLightSqr);
  43. return GetDistAtt(distToLightSqr, attRadiusSqrInv) * edgeAttenuation;
  44. }
  45. float CalculateAngleAttenuation(vec3 spotLightDir, vec3 L, float cosAngleOuter)
  46. {
  47. float cosInner = max(dot(spotLightDir, L), 0.01);
  48. float litAngleScale = 1.0 / max(0.001, cosInner - cosAngleOuter);
  49. float litAngleOffset = -cosAngleOuter * litAngleScale;
  50. return GetAngleAtt(L, spotLightDir, litAngleScale, litAngleOffset);
  51. }