noradninja

ShadowAtlasLight

Mar 8th, 2026 (edited)
52
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 3.54 KB | None | 0 0
  1. using UnityEngine;
  2.  
  3. [ExecuteInEditor]
  4. [RequireComponent(typeof(Light))]
  5. public class ShadowAtlasLight : MonoBehaviour
  6. {
  7.     public enum AtlasShadowLightType
  8.     {
  9.         Directional,
  10.         Spot
  11.     }
  12.  
  13.     [Header("Atlas Settings")]
  14.     public AtlasShadowLightType lightType = AtlasShadowLightType.Spot;
  15.     public int priority = 0;
  16.     public float closeDistance = 10f;
  17.     public ShadowUpdateMode updateMode = ShadowUpdateMode.WhenCloseElseEveryFifthFrame;
  18.     public int frameOffset = 0;
  19.  
  20.     [Header("Shadow Settings")]
  21.     public float shadowStrength = 1f;
  22.     public float bias = 0.001f;
  23.     public float normalBias = 0.02f;
  24.  
  25.     [Header("Runtime")]
  26.     [HideInInspector] public int atlasSlot = -1;
  27.     [HideInInspector] public bool registered;
  28.     [HideInInspector] public int lastRenderedFrame;
  29.     [HideInInspector] public bool dirty = true;
  30.     [HideInInspector] public bool forceRefresh = false;
  31.  
  32.     public Light unityLight { get; private set; }
  33.  
  34.     int _originalCullingMask;
  35.     bool _unityLightingSuppressed;
  36.  
  37.     Vector3 _lastPos;
  38.     Quaternion _lastRot;
  39.  
  40.     void Awake()
  41.     {
  42.         CacheLight();
  43.         CacheOriginalCullingMask();
  44.         CaptureCurrentTransform();
  45.     }
  46.  
  47.     void OnEnable()
  48.     {
  49.         CacheLight();
  50.         CacheOriginalCullingMask();
  51.     }
  52.  
  53.     void OnValidate()
  54.     {
  55.         CacheLight();
  56.         CacheOriginalCullingMask();
  57.  
  58.         if (unityLight != null)
  59.         {
  60.             if (unityLight.type == LightType.Directional)
  61.                 lightType = AtlasShadowLightType.Directional;
  62.             else if (unityLight.type == LightType.Spot)
  63.                 lightType = AtlasShadowLightType.Spot;
  64.         }
  65.     }
  66.  
  67.     void CacheLight()
  68.     {
  69.         if (unityLight == null)
  70.             unityLight = GetComponent<Light>();
  71.     }
  72.  
  73.     void CacheOriginalCullingMask()
  74.     {
  75.         if (unityLight == null)
  76.             return;
  77.  
  78.         if (!_unityLightingSuppressed)
  79.             _originalCullingMask = unityLight.cullingMask;
  80.     }
  81.  
  82.     public bool HasValidLight()
  83.     {
  84.         return unityLight != null && enabled && gameObject.activeInHierarchy && unityLight.enabled;
  85.     }
  86.  
  87.     public float GetCloseDistanceSqr()
  88.     {
  89.         return closeDistance * closeDistance;
  90.     }
  91.  
  92.     public void CaptureCurrentTransform()
  93.     {
  94.         _lastPos = transform.position;
  95.         _lastRot = transform.rotation;
  96.     }
  97.  
  98.     public bool TransformChanged()
  99.     {
  100.         return transform.position != _lastPos || transform.rotation != _lastRot;
  101.     }
  102.  
  103.     public void MarkDirty()
  104.     {
  105.         dirty = true;
  106.     }
  107.  
  108.     public void ClearDirty()
  109.     {
  110.         dirty = false;
  111.         forceRefresh = false;
  112.     }
  113.  
  114.     /* Suppresses Unity's normal lighting contribution while our atlas owns this light. */
  115.     public void SuppressUnityLighting()
  116.     {
  117.         if (unityLight == null)
  118.             return;
  119.  
  120.         if (_unityLightingSuppressed)
  121.             return;
  122.  
  123.         _originalCullingMask = unityLight.cullingMask;
  124.         unityLight.cullingMask = 0;
  125.         _unityLightingSuppressed = true;
  126.     }
  127.  
  128.     /* Restores Unity lighting so the light falls back to normal built-in processing. */
  129.     public void RestoreUnityLighting()
  130.     {
  131.         if (unityLight == null)
  132.             return;
  133.  
  134.         if (!_unityLightingSuppressed)
  135.             return;
  136.  
  137.         unityLight.cullingMask = _originalCullingMask;
  138.         _unityLightingSuppressed = false;
  139.     }
  140.  
  141.     public bool IsUnityLightingSuppressed()
  142.     {
  143.         return _unityLightingSuppressed;
  144.     }
  145. }
Advertisement
Add Comment
Please, Sign In to add comment