コード例 #1
0
        void AddBounds(CachedShadowMapLight a_light)
        {
            var bounding_sphere = BoundsUtility.ComputeLightBoundingSphere(a_light: a_light);

            if (this._LightBoundingSpheres.ContainsKey(key: a_light.LightComponent))
            {
                this._LightBoundingSpheres[key : a_light.LightComponent] = bounding_sphere;
            }
            else
            {
                this._LightBoundingSpheres.Add(key: a_light.LightComponent, value: bounding_sphere);
            }

            var light_bounds = BoundsUtility.ComputeLightBounds(light: a_light);

            if (this._LightBounds.ContainsKey(key: a_light.LightComponent))
            {
                this._LightBounds[key : a_light.LightComponent] = light_bounds;
            }
            else
            {
                this._LightBounds.Add(key: a_light.LightComponent, value: light_bounds);
            }

            this.ReceiverCamera?.RefreshCullingGroup();
        }
コード例 #2
0
        internal static bool DidDynamicObjectsChange(CachedShadowMapLight a_light, ref List <DynamicObject> dynamic_objects)
        {
            var changed = false;

            if (a_light && dynamic_objects.Count > 0)
            {
                for (var index = 0; index < dynamic_objects.Count; index++)
                {
                    var o = dynamic_objects[index : index];
                    var dynamic_object = o;
                    if (dynamic_object == null)
                    {
                        continue;
                    }

                    if (dynamic_object.ChangeEnableState ||
                        (dynamic_object.Moved &&
                         dynamic_object.isActiveAndEnabled &&
                         dynamic_object.gameObject.activeInHierarchy))
                    {
                        changed = true;
                    }
                }
            }

            return(changed);
        }
コード例 #3
0
        void EnsureCachedTextureExist(CachedShadowMapLight a_light)
        {
            if (this._CachedShadowMapTextures.ContainsKey(key: a_light.LightComponent))
            {
                if (this._CachedShadowMapTextures[key : a_light.LightComponent].width
                    == a_light.LightComponent.shadowCustomResolution &&
                    this._CachedShadowMapTextures[key : a_light.LightComponent].height
                    == a_light.LightComponent.shadowCustomResolution &&
                    this.TextureTypeFits(a_light : a_light) &&
                    this._CachedShadowMapTextures[key : a_light.LightComponent].depth
                    == (int)CachedShadowMapLight.MShadowMapBitDepth &&
                    this._CachedShadowMapTextures[key : a_light.LightComponent].IsCreated())
                {
                    return;
                }

                this._CachedShadowMapTextures[key : a_light.LightComponent].DiscardContents();
                this._CachedShadowMapTextures[key : a_light.LightComponent].Release();
                RenderTexture.DestroyImmediate(obj: this._CachedShadowMapTextures[key: a_light.LightComponent]);
                this._CachedShadowMapTextures.Remove(key: a_light.LightComponent);

                //this.CachedShadowMapTextures[aLight.LightComponent].MarkRestoreExpected();
            }

            ;

            var shadow_custom_resolution = a_light.LightComponent.shadowCustomResolution;
            var cached_shadow_map        =
                new RenderTexture(width: shadow_custom_resolution,
                                  height: shadow_custom_resolution,
                                  depth: (int)CachedShadowMapLight.MShadowMapBitDepth,
                                  format: RenderTextureFormat.Shadowmap)
            {
                antiAliasing =
                    (int)AntiAliasingEnum.None_,
                filterMode =
                    CachedShadowMapLight._MFilterMode,
                useMipMap        = false,
                autoGenerateMips = false,
                wrapMode         = TextureWrapMode.Clamp,
                memorylessMode   =
                    RenderTextureMemoryless.None,
                vrUsage         = VRTextureUsage.None,
                useDynamicScale = false,
                name            =
                    $"Cached Shadow Map for #{a_light.GetInstanceID()}",
                anisoLevel = CachedShadowMapLight
                             ._MAnisoLevel
            };

            if (a_light.LightComponent.type == LightType.Point)
            {
                cached_shadow_map.dimension = TextureDimension.Cube;
            }

            cached_shadow_map.Create();
            this._CachedShadowMapTextures[key : a_light.LightComponent] = cached_shadow_map;
        }
コード例 #4
0
        bool TextureTypeFits(CachedShadowMapLight a_light)
        {
            if (a_light.LightComponent.type == LightType.Point)
            {
                return(this._CachedShadowMapTextures[key : a_light.LightComponent].dimension == TextureDimension.Cube);
            }

            return(this._CachedShadowMapTextures[key : a_light.LightComponent].dimension == TextureDimension.Tex2D);
        }
コード例 #5
0
        /// <summary>
        /// Compute bounds of a point light, add the same(inflation) percentage to the range as when creating the light geometry.
        /// </summary>
        /// <param name="light"></param>
        /// <param name="inflation"></param>
        /// <returns></returns>
        public static Bounds ComputePointLightBounds(CachedShadowMapLight light, float inflation = _default_inflation)
        {
            var range = light.LightComponent.range;
            var dif   = new Vector3(x: range, y: range, z: range) * inflation;

            var min_bounds = light.CachedPosition - dif;
            var max_bounds = light.CachedPosition + dif;

            var bounds = new Bounds();

            bounds.SetMinMax(min: min_bounds, max: max_bounds);
            return(bounds);
        }
コード例 #6
0
        /// <summary>
        /// Compute bounds of a spot light
        /// </summary>
        /// <param name="light"></param>
        /// <param name="inflation"></param>
        /// <returns></returns>
        public static Bounds ComputeSpotLightBounds(CachedShadowMapLight light, float inflation = _default_inflation)
        {
            var transform = light.CachedTransform;
            var forward1  = transform.forward;
            var pos       = light.CachedPosition + -forward1 * (inflation - 1.0f);
            var forward   = forward1 * inflation;
            var right     = transform.right * inflation;
            var up        = transform.up * inflation;

            var far_center = pos + forward * light.LightComponent.range;

            var far_height = Mathf.Tan(f: light.LightComponent.spotAngle * 0.5f * Mathf.Deg2Rad) * light.LightComponent.range;

            var far_top_left     = far_center + up * (far_height) - right * (far_height);
            var far_top_right    = far_center + up * (far_height) + right * (far_height);
            var far_bottom_left  = far_center - up * (far_height) - right * (far_height);
            var far_bottom_right = far_center - up * (far_height) + right * (far_height);

            var min_bounds =
                new Vector3(x: Mathf.Min(a: far_top_left.x,
                                         b: Mathf.Min(a: far_top_right.x,
                                                      b: Mathf.Min(a: far_bottom_left.x,
                                                                   b: Mathf.Min(a: far_bottom_right.x, b: pos.x)))),
                            y: Mathf.Min(a: far_top_left.y,
                                         b: Mathf.Min(a: far_top_right.y,
                                                      b: Mathf.Min(a: far_bottom_left.y,
                                                                   b: Mathf.Min(a: far_bottom_right.y, b: pos.y)))),
                            z: Mathf.Min(a: far_top_left.z,
                                         b: Mathf.Min(a: far_top_right.z,
                                                      b: Mathf.Min(a: far_bottom_left.z,
                                                                   b: Mathf.Min(a: far_bottom_right.z, b: pos.z)))));
            var max_bounds =
                new Vector3(x: Mathf.Max(a: far_top_left.x,
                                         b: Mathf.Max(a: far_top_right.x,
                                                      b: Mathf.Max(a: far_bottom_left.x,
                                                                   b: Mathf.Max(a: far_bottom_right.x, b: pos.x)))),
                            y: Mathf.Max(a: far_top_left.y,
                                         b: Mathf.Max(a: far_top_right.y,
                                                      b: Mathf.Max(a: far_bottom_left.y,
                                                                   b: Mathf.Max(a: far_bottom_right.y, b: pos.y)))),
                            z: Mathf.Max(a: far_top_left.z,
                                         b: Mathf.Max(a: far_top_right.z,
                                                      b: Mathf.Max(a: far_bottom_left.z,
                                                                   b: Mathf.Max(a: far_bottom_right.z, b: pos.z)))));

            var bounds = new Bounds();

            bounds.SetMinMax(min: min_bounds, max: max_bounds);
            return(bounds);
        }
コード例 #7
0
        /// <summary>
        /// Disables the cached shadow map functionality for a single CachedShadowMapLight in system
        /// </summary>
        /// <param name="a_light"></param>
        protected internal virtual void RevertToDynamicLighting(CachedShadowMapLight a_light)
        {
            if (a_light && a_light.LightComponent)
            {
                a_light.LightComponent.enabled = true;
            }

      #if REMOVE_COMMANDBUFFERS_WHILE_NOT_ACTIVE
            if (this._captureCmdBuffers.ContainsKey(aLight.LightComponent))
            {
                aLight.LightComponent.RemoveCommandBuffer(captureEvent, this._captureCmdBuffers[a_light.LightComponent]);
                this._captureCmdBuffers[a_light.LightComponent].Clear();
            }

            if (this.BlitCmdBuffers.ContainsKey(aLight.LightComponent))
            {
                if (mainCamera?._camera)
                {
                    this.mainCamera._camera.RemoveCommandBuffer(blitEvent, this.BlitCmdBuffers[a_light.LightComponent]);
                }
                this.BlitCmdBuffers[a_light.LightComponent].Clear();
            }
      #endif

            if (this._CachedShadowMapTextures.ContainsKey(key: a_light.LightComponent))
            {
                this._CachedShadowMapTextures[key : a_light.LightComponent].DiscardContents();
                this._CachedShadowMapTextures[key : a_light.LightComponent].Release();
                //this.CachedShadowMapTextures[aLight.LightComponent].MarkRestoreExpected();
            }

            if (this._ActivelyCachedTextures.ContainsKey(key: a_light.LightComponent))
            {
                this._ActivelyCachedTextures.Remove(key: a_light.LightComponent);
            }

            if (this._ActivelyCachedLights.Contains(item: a_light.LightComponent))
            {
                this._ActivelyCachedLights.Remove(item: a_light.LightComponent);
            }

            if (this._ActivelyCachedShadowMaps.Contains(item: a_light))
            {
                this._ActivelyCachedShadowMaps.Remove(item: a_light);
            }

      #if UNITY_EDITOR && CACHED_SHADOW_MAP_DEBUG
            this.UpdateEditorDebugInfo();
      #endif
        }
コード例 #8
0
        void RemoveBounds(CachedShadowMapLight a_light)
        {
            if (this._LightBoundingSpheres.ContainsKey(key: a_light.LightComponent))
            {
                this._LightBoundingSpheres.Remove(key: a_light.LightComponent);
            }

            if (this._LightBounds.ContainsKey(key: a_light.LightComponent))
            {
                this._LightBounds.Remove(key: a_light.LightComponent);
            }

            this.ReceiverCamera?.RefreshCullingGroup();
        }
コード例 #9
0
        internal static bool DidIntersectingDynamicsObjectChange(CachedShadowMapLight a_light,
                                                                 ref List <DynamicObject> dynamic_objects,
                                                                 bool only_when_intersecting = true)
        {
            var changed = false;

            if (a_light)
            {
                for (var index = 0; index < dynamic_objects.Count; index++)
                {
                    var dynamic_object = dynamic_objects[index : index];
                    var intersects     = false;
                    if (dynamic_object)
                    {
                        switch (a_light.LightComponent.type)
                        {
                        case LightType.Spot:
                            intersects = ConeSphereIntersection(spot_light: a_light, dynamic_object: dynamic_object);
                            break;

                        case LightType.Point:
                            intersects = SphereSphereIntersection(point_light: a_light, dynamic_object: dynamic_object);
                            break;

                        case LightType.Directional:
                        case LightType.Area:
                        case LightType.Disc:
                            break;

                        default:
                            throw new ArgumentOutOfRangeException();
                        }

                        if (intersects || !only_when_intersecting)
                        {
                            if (dynamic_object.ChangeEnableState ||
                                (dynamic_object.Moved &&
                                 dynamic_object.isActiveAndEnabled &&
                                 dynamic_object.gameObject.activeInHierarchy))
                            {
                                changed = true;
                            }
                        }
                    }
                }
            }

            return(changed);
        }
コード例 #10
0
        /// <summary>
        /// see https://www.geometrictools.com/Documentation/IntersectionSphereCone.pdf
        /// </summary>
        /// <param name="spot_light"></param>
        /// <param name="dynamic_object"></param>
        /// <returns></returns>
        public static bool ConeSphereIntersection(CachedShadowMapLight spot_light,
                                                  DynamicObject dynamic_object)
        {
            // FIXME Optimize computations of boundingSphereRadius^2, 1.0f / Mathf.Sin(angle * 0.5f), Mathf.Sin(angle * 0.5f)^2 and  Mathf.Cos(angle * 0.5f)^2
            var sin    = Mathf.Sin(f: spot_light.LightComponent.spotAngle * 0.5f * Mathf.Deg2Rad);
            var cos    = Mathf.Cos(f: spot_light.LightComponent.spotAngle * 0.5f * Mathf.Deg2Rad);
            var offset = (dynamic_object.boundingSphereRadius / sin);
            var u      = spot_light.CachedPosition - offset * spot_light.CachedForward; // Assumes unit length forward.
            var d      = dynamic_object.CachedPosition + dynamic_object.offset - u;

            var distance = Vector3.Dot(lhs: spot_light.CachedForward, rhs: d);   // Assumes unit length forward.

            return(distance >= d.magnitude * cos &&
                   distance <= offset + spot_light.LightComponent.range + dynamic_object.boundingSphereRadius);
        }
コード例 #11
0
        /// <summary>
        /// Removes a cachedShadowMapLight from the system, removes, disposes, releases CommandBuffers and RenderTextures for the light
        /// </summary>
        /// <param name="a_light"></param>
        public void RemoveLightFromSystem(CachedShadowMapLight a_light)
        {
      #if !REMOVE_COMMANDBUFFERS_WHILE_NOT_ACTIVE
            if (this._CaptureCmdBuffers.ContainsKey(key: a_light.LightComponent))
            {
                a_light.LightComponent.RemoveCommandBuffer(evt: this._capture_event,
                                                           buffer: this._CaptureCmdBuffers[key: a_light
                                                                                           .LightComponent]);
            }

            if (this._BlitCmdBuffers.ContainsKey(key: a_light.LightComponent))
            {
                this.ReceiverCamera?._camera.RemoveCommandBuffer(evt: this._blit_event,
                                                                 buffer: this._BlitCmdBuffers[key: a_light
                                                                                              .LightComponent]);
            }
      #endif

            this.RevertToDynamicLighting(a_light: a_light);

            this.RemoveBounds(a_light: a_light);

            this._AllCachedLightComponents.Remove(item: a_light);

            // Remove and dispose command buffers.
            if (this._CaptureCmdBuffers.ContainsKey(key: a_light.LightComponent))
            {
                var shadow_map_cache_buffer = this._CaptureCmdBuffers[key : a_light.LightComponent];
                this._CaptureCmdBuffers.Remove(key: a_light.LightComponent);
                shadow_map_cache_buffer.Dispose();
            }

            if (this._BlitCmdBuffers.ContainsKey(key: a_light.LightComponent))
            {
                var lighting_buffer = this._BlitCmdBuffers[key : a_light.LightComponent];
                this._BlitCmdBuffers.Remove(key: a_light.LightComponent);
                lighting_buffer.Dispose();
            }

            // Remove and release render texture.
            if (this._CachedShadowMapTextures.ContainsKey(key: a_light.LightComponent))
            {
                this._CachedShadowMapTextures[key : a_light.LightComponent].Release();
                RenderTexture.DestroyImmediate(obj: this._CachedShadowMapTextures[key: a_light.LightComponent]);
                this._CachedShadowMapTextures.Remove(key: a_light.LightComponent);
            }
        }
コード例 #12
0
        /// <summary>
        /// Compute bounding sphere of a spot light
        /// See illustration at https://www.mathalino.com/sites/default/files/users/Mathalino/differential-calculus/063-cone-inscribed-in-sphere.jpg
        /// </summary>
        /// <param name="light"></param>
        /// <param name="inflation"></param>
        /// <returns></returns>
        public static BoundingSphere ComputeSpotLightBoundingSphere(CachedShadowMapLight light, float inflation = _default_inflation)
        {
            if (light.LightComponent.spotAngle < 90.0f)
            {
                var r = Mathf.Tan(f: light.LightComponent.spotAngle * 0.5f * Mathf.Deg2Rad) * light.LightComponent.range;
                var h = light.LightComponent.range;
                var a = (r * r + h * h) / (2.0f * h);

                return(new BoundingSphere(pos: light.CachedPosition + light.CachedForward * a, rad: a * inflation));
            }
            else
            {
                var r = Mathf.Tan(f: light.LightComponent.spotAngle * 0.5f * Mathf.Deg2Rad) * light.LightComponent.range;

                return(new BoundingSphere(pos: light.CachedPosition + light.CachedForward * light.LightComponent.range, rad: r * inflation));
            }
        }
コード例 #13
0
        internal static void RemoveNonOverlapping(CachedShadowMapLight a_light, ref List <DynamicObject> dynamic_objects)
        {
            if (dynamic_objects.Count < 1 || !a_light)
            {
                return;
            }

            for (var i = dynamic_objects.Count - 1; i >= 0; i--)
            {
                if (NotIntersecting(a_light : a_light, dynamic_object : dynamic_objects[index : i]))
                {
                    dynamic_objects.RemoveAt(index: i);
                }
            }

            // dynamic_objects.RemoveAll(o=>NotIntersecting(aLight,o)); // GENERATES GARBAGE!
        }
コード例 #14
0
        /// <summary>
        /// Compute bounds of light
        /// </summary>
        /// <param name="light"></param>
        /// <param name="inflation"></param>
        /// <returns></returns>
        public static Bounds ComputeLightBounds(CachedShadowMapLight light, float inflation = _default_inflation)
        {
            if (light)
            {
                switch (light.LightComponent.type)
                {
                case LightType.Spot: {
                    return(ComputeSpotLightBounds(light: light, inflation: inflation));
                }

                case LightType.Point: {
                    return(ComputePointLightBounds(light: light, inflation: inflation));
                }
                }
            }

            return(new Bounds());
        }
コード例 #15
0
        /// <summary>
        /// Compute bounding sphere of light
        /// </summary>
        /// <param name="a_light"></param>
        /// <param name="inflation"></param>
        /// <returns></returns>
        public static BoundingSphere ComputeLightBoundingSphere(CachedShadowMapLight a_light, float inflation = _default_inflation)
        {
            if (a_light.LightComponent)
            {
                switch (a_light.LightComponent.type)
                {
                case LightType.Spot: {
                    return(ComputeSpotLightBoundingSphere(light: a_light, inflation: inflation));
                }

                case LightType.Point: {
                    return(new BoundingSphere(pos: a_light.CachedPosition, rad: a_light.LightComponent.range * inflation));
                }
                }
            }

            return(new BoundingSphere());
        }
コード例 #16
0
        void EnsureCaptureCmdBufferExist(CachedShadowMapLight a_light)
        {
            if (!this._CaptureCmdBuffers.ContainsKey(key: a_light.LightComponent))
            {
                var s = new CommandBuffer {
                    name =
                        $"Shadow Map Cache #{unchecked(this._capture_id++)} #CID{a_light.GetInstanceID()}"
                };
                //unchecked wraps integer instead of throwing exception
                a_light.LightComponent.AddCommandBuffer(evt: this._capture_event, buffer: s);
                this._CaptureCmdBuffers.Add(key: a_light.LightComponent, value: s);
            }

            a_light.LightComponent.RemoveCommandBuffer(evt: this._capture_event,
                                                       buffer: this._CaptureCmdBuffers
                                                       [key: a_light.LightComponent]);
            a_light.LightComponent.AddCommandBuffer(evt: this._capture_event,
                                                    buffer: this._CaptureCmdBuffers[key: a_light.LightComponent]);
        }
コード例 #17
0
        void EnsureBlitCmdBufferExist(CachedShadowMapLight a_light)
        {
            if (!this._BlitCmdBuffers.ContainsKey(key: a_light.LightComponent))
            {
                var lighting_buffer = new CommandBuffer {
                    name =
                        $"Cached Shadow Map #{unchecked(this._blit_id++)} #CID{a_light.LightComponent.GetInstanceID()}"
                };
                //unchecked wraps integer instead of throwing exception

                this._BlitCmdBuffers.Add(key: a_light.LightComponent, value: lighting_buffer);
            }

            this.ReceiverCamera?._camera.RemoveCommandBuffer(evt: this._blit_event,
                                                             buffer: this._BlitCmdBuffers[key: a_light
                                                                                          .LightComponent]);
            this.ReceiverCamera?._camera.AddCommandBuffer(evt: this._blit_event,
                                                          buffer: this._BlitCmdBuffers
                                                          [key: a_light.LightComponent]);
        }
コード例 #18
0
        /// <summary>
        /// Enqueue a CachedShadowMapLight to be cached
        /// </summary>
        /// <param name="a_light"></param>
        public void EnqueueDirtyCandidate(CachedShadowMapLight a_light)
        {
            if (this.DirtyCachedLights.Contains(item: a_light))
            {
                return;
            }

            if (a_light && a_light.LightComponent)
            {
        #if CACHED_SHADOW_MAP_DEBUG
                if (!aLight.isActiveAndEnabled)
                {
                    Debug.LogError("Light was not isActiveAndEnabled", aLight);
                }

                if (this.DirtyCachedLights.Contains(aLight))
                {
                    Debug.LogError("Light was already enqueued", aLight);
                }
        #endif

                this.DirtyCachedLights.Enqueue(item: a_light);
            }
        }
コード例 #19
0
        static bool NotIntersecting(CachedShadowMapLight a_light, DynamicObject dynamic_object)
        {
            if (dynamic_object && dynamic_object.isActiveAndEnabled && dynamic_object.gameObject.activeInHierarchy)
            {
                switch (a_light.LightComponent.type)
                {
                case LightType.Spot:
                    return(!ConeSphereIntersection(spot_light: a_light, dynamic_object: dynamic_object));

                case LightType.Point:
                    return(!SphereSphereIntersection(point_light: a_light, dynamic_object: dynamic_object));

                case LightType.Directional:
                case LightType.Area:
                case LightType.Disc:
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }
            }

            return(true);
        }
コード例 #20
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="point_light"></param>
        /// <param name="dynamic_object"></param>
        /// <returns></returns>
        public static bool SphereSphereIntersection(CachedShadowMapLight point_light, DynamicObject dynamic_object)
        {
            var diff = dynamic_object.CachedPosition + dynamic_object.offset - point_light.CachedPosition;

            return(diff.magnitude - dynamic_object.boundingSphereRadius <= point_light.LightComponent.range);
        }
コード例 #21
0
 /// <summary>
 /// Adds a cachedShadowMapLight to the system, sets up a renderTexture to be rendered into by the light
 /// </summary>
 /// <param name="a_light"></param>
 public void AddLightToSystem(CachedShadowMapLight a_light)
 {
     this._AllCachedLightComponents.Add(item: a_light);
     this.EnsureCachedTextureExist(a_light: a_light);
 }
コード例 #22
0
 protected internal override void RevertToDynamicLighting(CachedShadowMapLight aLight)
 {
     base.RevertToDynamicLighting(aLight);
     HxVolumetricCamera.SetCachedShadowMaps(ActivelyCachedLights, ActivelyCachedTextures);
 }
コード例 #23
0
 private protected override void ComputeCachedShadowMap(CachedShadowMapLight light, float margin = 2)
 {
     base.ComputeCachedShadowMap(light, margin);
     HxVolumetricCamera.SetCachedShadowMaps(ActivelyCachedLights, ActivelyCachedTextures);
 }
コード例 #24
0
        private protected virtual void ComputeCachedShadowMap(CachedShadowMapLight a_light, float margin = 2f)
        {
            if (!a_light || !a_light.isActiveAndEnabled || !a_light.LightComponent)
            {
        #if CACHED_SHADOW_MAP_DEBUG
                Debug.LogWarning($"light was null!!!", aLight);
        #endif
                this.RevertToDynamicLighting(a_light: a_light);
                return;
            }

            //Debug.Log("Updating CSM " + aLight.name, aLight);
            this.EnsureCaptureCmdBufferExist(a_light: a_light);
            this.EnsureCachedTextureExist(a_light: a_light);

            var capture_cmd_buffer = this._CaptureCmdBuffers[key : a_light.LightComponent];

            a_light.LightComponent.enabled =
                true; // Make sure the light source is on while we render using the caching camera

            var cull_d = a_light.LightComponent.layerShadowCullDistances;
            a_light.LightComponent.layerShadowCullDistances = null;

            var lrm = a_light.LightComponent.renderMode;
            a_light.LightComponent.renderMode = LightRenderMode.ForcePixel;

            var lscm = a_light.LightComponent.lightShadowCasterMode;
            a_light.LightComponent.lightShadowCasterMode = LightShadowCasterMode.Everything;

      #if PRERENDER_CONTEXT
            #if PRECLEAR_SHADOW_MAP
            captureCmdBuffer.SetRenderTarget(this.CachedShadowMapTextures[aLight.LightComponent]);
            captureCmdBuffer.ClearRenderTarget(true, false, Color.black);
            #endif

            this.camera.CacheShadowMapOfLight(aLight, margin);
            captureCmdBuffer.Clear();
      #endif
      #if SHADOW_MAP_UPDATE_CHECK
            var last_update_count = this._CachedShadowMapTextures[key : a_light.LightComponent].updateCount;
            capture_cmd_buffer.IncrementUpdateCount(dest: this._CachedShadowMapTextures
                                                    [key: a_light.LightComponent]);
      #endif

            capture_cmd_buffer.CopyTexture(src: BuiltinRenderTextureType.CurrentActive,
                                           dst: this._CachedShadowMapTextures[key: a_light.LightComponent]);

            this.cachingCamera.CacheShadowMapOfLight(a_light: a_light,
                                                     margin:
                                                     margin); // Reset camera and set light specific parameters.

            capture_cmd_buffer.Clear();
            a_light.LightComponent.renderMode = lrm;
            a_light.LightComponent.layerShadowCullDistances = cull_d;
            a_light.LightComponent.lightShadowCasterMode    = lscm;

      #if SHADOW_MAP_UPDATE_CHECK
            if (last_update_count == this._CachedShadowMapTextures[key : a_light.LightComponent].updateCount)
            {
                Debug.LogError("CachedShadowMap was not updated!");
                this.RevertToDynamicLighting(a_light: a_light);
                this.EnqueueDirtyCandidate(a_light: a_light);
                return;
            }
      #endif

      #if SHADOW_MAP_SANITY_CHECK
            if (ShadowMapChecking.SanityCheck(CachedShadowMapTextures[aLight.LightComponent]) &&
                CachedShadowMapTextures[aLight.LightComponent].IsCreated())
            {
                RevertToDynamicLighting(aLight);
                EnqueueDirtyCandidate(aLight);
                return;
            }
      #endif

            this.AddBounds(a_light: a_light);

            this.EnsureBlitCmdBufferExist(a_light: a_light);

            if (!this._ActivelyCachedLights.Contains(item: a_light.LightComponent))
            {
                this._ActivelyCachedLights.Add(item: a_light.LightComponent);
            }

            if (!this._ActivelyCachedShadowMaps.Contains(item: a_light))
            {
                this._ActivelyCachedShadowMaps.Add(item: a_light);
            }

            if (!this._ActivelyCachedTextures.ContainsKey(key: a_light.LightComponent))
            {
                this._ActivelyCachedTextures.Add(key: a_light.LightComponent,
                                                 value: this._CachedShadowMapTextures[key: a_light.LightComponent]);
            }

            a_light.LightComponent.enabled = false;

      #if UNITY_EDITOR && CACHED_SHADOW_MAP_DEBUG
            this.UpdateEditorDebugInfo();
      #endif
        }