Ejemplo n.º 1
0
    public Vector3 ReserveDirectionalShadows(Light light, int visibleLightIndex)
    {
        if (
            shadowedDirectionalLightCount <= maxShadowedDirectionalLightCount &&
            light.shadows != LightShadows.None &&
            light.shadowStrength > 0f &&
            cullingResults.GetShadowCasterBounds(visibleLightIndex, out Bounds b)
            )
        {
            ShadowedDirectionalLights[shadowedDirectionalLightCount] = new ShadowedDirectionalLight {
                visibleLightIndex = visibleLightIndex,
                slopeScaleBias    = light.shadowBias,
                nearPlaneOffset   = light.shadowNearPlane
            };

            return(new Vector3(
                       light.shadowStrength,
                       settings.directional.cascadeCount * shadowedDirectionalLightCount++,
                       light.shadowNormalBias
                       ));
        }
        else
        {
            return(Vector3.zero);
        }
    }
Ejemplo n.º 2
0
        void RenderDirectionalShadows(int index, int split, int tileSize)
        {
            ShadowedDirectionalLight light = shadowedDirectionalLights[index];
            var shadowSettings             = new ShadowDrawingSettings(cullingResults, light.visibleLightIndex);

            var     cascadeCount = settings.directional.cascadeCount;
            int     tileOffset   = index * cascadeCount;
            Vector3 ratios       = settings.directional.CascadeRatios;

            float cullingFactor = Mathf.Max(0, 0.8f - settings.directional.cascadeFade);

            for (int i = 0; i < cascadeCount; i++)
            {
                cullingResults.ComputeDirectionalShadowMatricesAndCullingPrimitives(light.visibleLightIndex, i, cascadeCount,
                                                                                    ratios, tileSize, light.nearPlaneOffset,
                                                                                    out Matrix4x4 viewMatrix, out Matrix4x4 projectionMatrix,
                                                                                    out ShadowSplitData splitData);
                splitData.shadowCascadeBlendCullingFactor = cullingFactor;
                shadowSettings.splitData = splitData;
                if (index == 0)
                {
                    SetCascadeData(i, splitData.cullingSphere, tileSize);
                }
                int tileOffIndex = tileOffset + i;
                dirShadowMatrices[tileOffIndex] = ConvertToAtlasMatrix(projectionMatrix * viewMatrix, SetTileViewport(tileOffIndex, split, tileSize), split);
                buffer.SetViewProjectionMatrices(viewMatrix, projectionMatrix);
                buffer.SetGlobalDepthBias(0f, light.slopeScaleBias);
                ExecuteBuffer();
                context.DrawShadows(ref shadowSettings);
                buffer.SetGlobalDepthBias(0f, 0f);
            }
        }
Ejemplo n.º 3
0
    public Vector4 ReserveDirectionalShadows(Light light, int visibleLightIndex)
    {
        if (shadowedDirectionalLightCount < maxShadowedDirectionalLightCount &&
            light.shadows != LightShadows.None && light.shadowStrength > 0f             //&&
            //cullingResults.GetShadowCasterBounds(visibleLightIndex, out Bounds b)
            )
        {
            float             maskChannel = -1;
            LightBakingOutput lightBaking = light.bakingOutput;
            if (lightBaking.lightmapBakeType == LightmapBakeType.Mixed &&
                lightBaking.mixedLightingMode == MixedLightingMode.Shadowmask)
            {
                useShadowMask = true;
                maskChannel   = lightBaking.occlusionMaskChannel;
            }

            if (!cullingResults.GetShadowCasterBounds(visibleLightIndex, out Bounds b))
            {
                return(new Vector4(-light.shadowStrength, 0f, 0f, maskChannel));
            }

            shadowedDirectionalLights[shadowedDirectionalLightCount] =
                new ShadowedDirectionalLight {
                visibleLightIndex = visibleLightIndex,
                slopeScaleBias    = light.shadowBias,
                nearPlaneOffset   = light.shadowNearPlane
            };

            return(new Vector4(light.shadowStrength, shadowSettings.directional.cascadeCount * shadowedDirectionalLightCount++, light.shadowNormalBias, maskChannel));
        }

        return(new Vector4(0f, 0f, 0f, -1f));
    }
Ejemplo n.º 4
0
 public override void HandleDirectional(VisibleLight light, int index, CullingResults results)
 {
     if (index == 0)
     {
         shadowmapLightCount = 0;
     }
     //判断如果不超数,灯光投影设置开,投影强度不为0且投影在视锥体内
     if (shadowmapLightCount < shadowSetting.directional.maxShadowedDirectionalLightCount &&
         light.light.shadows != LightShadows.None && light.light.shadowStrength > 0f &&
         results.GetShadowCasterBounds(index, out Bounds b))
     {
         //给投影灯组添加该投影灯
         shadowmapLights[shadowmapLightCount] = new ShadowedDirectionalLight {
             visibleLightIndex = index,
             slopeScaleBias    = light.light.shadowBias,
             nearPlaneOffset   = light.light.shadowNearPlane
         };
         //返回灯光的阴影强度和shadowmaId
         allDirectionalLightShadowData[index] =
             new Vector3(light.light.shadowStrength, shadowmapLightCount++, light.light.shadowNormalBias);
     }
     else
     {
         allDirectionalLightShadowData[index] = Vector2.zero;
     }
 }
Ejemplo n.º 5
0
    void RenderDirectionalShadows(int index, int split, int tileSize)
    {
        ShadowedDirectionalLight light = ShadowedDirectionalLights[index];
        var shadowSettings             =
            new ShadowDrawingSettings(cullingResults, light.visibleLightIndex);
        int cascadeCount = settings.directional.cascadeCount;
        int tileOffset   = index * cascadeCount;

        for (int i = 0; i < cascadeCount; i++)
        {
            cullingResults.ComputeDirectionalShadowMatricesAndCullingPrimitives(
                light.visibleLightIndex, i, cascadeCount, cascadeRatio,
                tileSize, 0f, out Matrix4x4 viewMatrix, out Matrix4x4 projMatrix, out ShadowSplitData shadowSplitData
                );
            shadowSettings.splitData = shadowSplitData;

            int tileIndex = tileOffset + i;
            dirShadowMatrices[tileIndex] = ConvertToAtlasMatrix(
                projMatrix * viewMatrix,
                SetTileViewport(tileIndex, split, tileSize), split
                );
            buffer.SetViewProjectionMatrices(viewMatrix, projMatrix);
            ExecuteBuffer();
            context.DrawShadows(ref shadowSettings);
        }
    }
Ejemplo n.º 6
0
    void RenderDirectionalShadows(int index, int split, int tileSize)
    {
        ShadowedDirectionalLight light = ShadowedDirectionalLights[index];

        //create a shadowdrawsetting based on the light index
        var shadowDSettings = new ShadowDrawingSettings(cullingResults, light.visibleLightIndex)
        {
            useRenderingLayerMaskTest = true
        };                                  //make shadow effcted by rendering layer mask

        //take into count that each light will render max 4 cascades
        int     cascadeCount = shadowSettings.directional.cascadeCount;
        int     tileOffset   = index * cascadeCount;
        Vector3 ratios       = shadowSettings.directional.CascadeRatios;
        //cal the cascade culling factor, make it 0.8-fade to make sure casters in transition not being culled
        float cullingfactor = Mathf.Max(0f, 0.8f - shadowSettings.directional.cascadeFade);

        float tileScale = 1f / split;

        //get the lightviewMatrix, lightprojectionMatrix, clip space box for the dirctional lights
        for (int i = 0; i < cascadeCount; i++)
        {
            cullingResults.ComputeDirectionalShadowMatricesAndCullingPrimitives(
                light.visibleLightIndex, i, cascadeCount, ratios, tileSize, light.nearPlaneOffset,
                out Matrix4x4 viewMatrix, out Matrix4x4 projectionMatrix,
                out ShadowSplitData splitData);
            //make UNITY to cull some shadow caster in large cascade if the smaller cascade is enough
            splitData.shadowCascadeBlendCullingFactor = cullingfactor;
            shadowDSettings.splitData = splitData;
            //assign the cascade culling sphere, all lights uses the same culling spheres and same cascade datas
            if (index == 0)
            {
                SetCascadeData(i, splitData.cullingSphere, tileSize);
            }
            int tileIdex = tileOffset + i;

            //set the render view port and get the offset for modify the dir shadow matrix
            //set the matrix from wolrd space to shadow Atlas space
            dirShadowMatrices[tileIdex] = ConvertToAtlasMatrix(
                projectionMatrix * viewMatrix,
                SetTileViewport(tileIdex, split, tileSize),
                tileScale
                );
            //set the ViewProjectionMatrices for the buffer
            buffer.SetViewProjectionMatrices(viewMatrix, projectionMatrix);

            //experimental depth bias
            //buffer.SetGlobalDepthBias(50000f, 0f);
            //using slop bias
            buffer.SetGlobalDepthBias(0f, light.slopScaleBias);
            ExecuteBuffer();

            //draw shadow caster on the buffer
            context.DrawShadows(ref shadowDSettings);
            //Debug.Log(shadowDSettings
            buffer.SetGlobalDepthBias(0f, 0f);
        }
    }
Ejemplo n.º 7
0
 public void ReserveDirectionalShadows(Light light, int visibleLightIndex)
 {
     if (ShadowedDirectionalLightCount < maxShadowedDirectionalLightCount &&
         light.shadows != LightShadows.None && light.shadowStrength > 0f &&
         cullingResults.GetShadowCasterBounds(visibleLightIndex, out Bounds b))
     {
         ShadowedDirectionalLights[ShadowedDirectionalLightCount++] =
             new ShadowedDirectionalLight {
             visibleLightIndex = visibleLightIndex
         };
     }
 }
Ejemplo n.º 8
0
 public void ReserveDirectionalShadows(Light light, int index)
 {
     if (_shadowedDirectionalLightCount < MaxShadowedDirectionalLightCount &&
         light.shadows != LightShadows.None && light.intensity > 0 &&
         _results.GetShadowCasterBounds(index, out Bounds outBounds))
     {
         ShadowedDirectionalLights[_shadowedDirectionalLightCount] = new ShadowedDirectionalLight()
         {
             visibleLightIndex = index
         };
         ++_shadowedDirectionalLightCount;
     }
 }
Ejemplo n.º 9
0
 public void ReserveDirectionalShadows(Light light, int visibleLightIndex)
 {
     ///it's possible that a visible light ends up not affecting any objects that cast shadows,
     ///either because they're configured not to or because the light only affects objects beyond the max shadow distance.
     if (ShadowedDirectionalLightCount < maxShadowedDirectionalLightCount &&
         light.shadows != LightShadows.None && light.shadowStrength > 0f &&
         cullingResults.GetShadowCasterBounds(visibleLightIndex, out Bounds b))
     {
         ShadowedDirectionalLights[ShadowedDirectionalLightCount++] =
             new ShadowedDirectionalLight
         {
             visibleLightIndex = visibleLightIndex
         };
     }
 }
Ejemplo n.º 10
0
    void RenderDirectionalShadows(int index, int split, int tileSize)
    {
        ShadowedDirectionalLight light = ShadowedDirectionalLights[index];
        var shadowSettings             = new ShadowDrawingSettings(cullingResults, light.visibleLightIndex);

        cullingResults.ComputeDirectionalShadowMatricesAndCullingPrimitives(
            light.visibleLightIndex, 0, 1, Vector3.zero, tileSize, 0f,
            out Matrix4x4 viewMatrix, out Matrix4x4 projectionMatrix,
            out ShadowSplitData splitData
            );
        shadowSettings.splitData = splitData;
        SetTileViewport(index, split, tileSize);
        buffer.SetViewProjectionMatrices(viewMatrix, projectionMatrix);
        ExecuteBuffer();
        context.DrawShadows(ref shadowSettings);
    }
Ejemplo n.º 11
0
    public void RenderDirectionalShadows(int index, int splitCount, int size)
    {
        ShadowedDirectionalLight light = ShadowedDirectionalLights[index];
        var shadowSetting = new ShadowDrawingSettings(_results, light.visibleLightIndex);

        //https://docs.unity3d.com/2019.1/Documentation/ScriptReference/Rendering.CullingResults.ComputeDirectionalShadowMatricesAndCullingPrimitives.html
        //利用光源的方向(-transform.forward)方向可以求出view matrix,nearclip 和 最远的阴影距离等可以求出project matrix等等
        _results.ComputeDirectionalShadowMatricesAndCullingPrimitives(light.visibleLightIndex, 0, 1, Vector3.zero,
                                                                      size, 0, out Matrix4x4 viewMatrix, out Matrix4x4 projMatrix,
                                                                      out ShadowSplitData shadowSplitData);
        shadowSetting.splitData = shadowSplitData;
        SetTileViewport(index, splitCount, size);
        _commandBuffer.SetViewProjectionMatrices(viewMatrix, projMatrix);
        ExecuteCommandBuffer();
        _context.DrawShadows(ref shadowSetting);
    }
Ejemplo n.º 12
0
    public Vector2 ReserveDirectionalShadows(Light light, int visibleLightIndex)
    {
        if (ShadowedDirectionalLightCount < maxShadowedDirectionalLightCount &&
            light.shadows != LightShadows.None && light.shadowStrength > 0.0f &&
            cullingResults.GetShadowCasterBounds(visibleLightIndex, out Bounds b))
        {
            ShadowedDirectionalLights[ShadowedDirectionalLightCount] =
                new ShadowedDirectionalLight
            {
                visibleLightIndex = visibleLightIndex
            };

            return(new Vector2(light.shadowStrength, settings.directional.cascadeCount * ShadowedDirectionalLightCount++));
        }

        return(Vector2.zero);
    }
Ejemplo n.º 13
0
        /// <summary>
        /// 处理每一栈平行光的shadowmap
        /// </summary>
        /// <param name="index"></param>
        /// <param name="split"></param>
        /// <param name="tileSize"></param>
        void RenderDirectionalShadows(int index, int split, int tileSize)
        {
            ShadowedDirectionalLight light = shadowmapLights[index];
            //前两个参数为剪裁结果和投影光在有效光中的索引
            ShadowDrawingSettings shadowSettings = new ShadowDrawingSettings(cullingResults, light.visibleLightIndex);

            int     cascadeCount = shadowSetting.directional.CascadeCount;
            Vector3 ratios       = shadowSetting.directional.CascadeRatios;
            int     tileOffset   = index * cascadeCount;

            for (int i = 0; i < cascadeCount; i++)
            {
                //其中第二三四参数为级联索引、级联数和级联比率,我们暂时不考虑,直接传入0,1,vector3.zero即可。然后是每个分块的阴影图分辨率,阴影近裁面偏移。之后输出所需的3个参数。
                cullingResults.ComputeDirectionalShadowMatricesAndCullingPrimitives(light.visibleLightIndex, i, cascadeCount, ratios, tileSize, light.nearPlaneOffset, out Matrix4x4 viewMatrix, out Matrix4x4 projectionMatrix, out ShadowSplitData splitData);
                //Unity通过为每个级联创建一个裁切球来确定覆盖的区域, 裁切球的作用还可以用来确定从哪个级联进行采样
                if (index == 0)
                {
                    Vector4 cullingSphere = splitData.cullingSphere;
                    //一个像素对应的距离大小
                    float texelSize  = 2f * cullingSphere.w / tileSize;
                    float filterSize = texelSize * ((float)shadowSetting.directional.filter + 1f);
                    cullingSphere.w         -= filterSize;
                    cullingSphere.w         *= cullingSphere.w;
                    cascadeCullingSpheres[i] = cullingSphere;
                    castedNormalBias[i]      = filterSize * 1.4142136f;
                }


                //获取世界转灯光空间矩阵,用于采样阴影图
                int       tileIndex = tileOffset + i;
                Matrix4x4 vp        = projectionMatrix * viewMatrix;
                shadowmapMatrices[tileIndex] = vp.ConvertToAtlasMatrix(tileIndex, split, tileSize, out Rect viewport);
                //设置当前联级区域的viewport?
                buffer.SetViewport(viewport);
                //更改渲染阴影的灯光相机VP矩阵
                buffer.SetViewProjectionMatrices(viewMatrix, projectionMatrix);
                buffer.SetGlobalDepthBias(0, light.slopeScaleBias);
                ExecuteBufferAndClear();
                //最后一个参数设置为true,为使用shadowlayermask进行过滤
                shadowSettings.useRenderingLayerMaskTest = true;
                //还有一个参数为级联阴影数据。
                shadowSettings.splitData = splitData;
                context.DrawShadows(ref shadowSettings);
                buffer.SetGlobalDepthBias(0f, 0f);
            }
        }
Ejemplo n.º 14
0
    public Vector2 ReserveDirectionalShadows(Light light, int visibleLightIndex)
    {
        // Check if the light can project a shadow and if the rendered elements are within bounds.
        if (shadowDirectionalLightCount < MaxShadowedDirectonalLightCount &&
            light.shadows != LightShadows.None &&
            light.shadowStrength > 0 &&
            cullingResults.GetShadowCasterBounds(visibleLightIndex, out Bounds bounds))
        {
            ShadowedDirectionalLights[shadowDirectionalLightCount] = new ShadowedDirectionalLight {
                VisibleLightIndex = visibleLightIndex
            };

            return(new Vector2(light.shadowStrength, shadowDirectionalLightCount++));
        }
        ;

        return(Vector2.zero);
    }
        void RenderDirectionalShadows(int index, int split, int tileSize)
        {
            ShadowedDirectionalLight light = _shadowedDirectionalLights[index];
            var     shadowSettings         = new ShadowDrawingSettings(_cullingResults, light.visibleLightIndex);
            int     splitCount             = _settings.directional.cascadeCount;
            Vector3 splitRatios            = _settings.directional.CascadeRatios;
            float   cullingFactor          = Mathf.Max(0f, 0.8f - _settings.directional.cascadeFade);

            for (int i = 0; i < splitCount; i++)
            {
                _cullingResults.ComputeDirectionalShadowMatricesAndCullingPrimitives(
                    light.visibleLightIndex,
                    splitIndex: i,
                    splitCount,
                    splitRatios,
                    shadowResolution: tileSize,
                    light.nearPlaneOffset,
                    out Matrix4x4 viewMatrix, out Matrix4x4 projectionMatrix,
                    out ShadowSplitData splitData
                    );

                splitData.shadowCascadeBlendCullingFactor = cullingFactor;
                _settings.SplitData = splitData;
                if (index == 0)
                {
                    SetCascadeData(i, splitData.cullingSphere, tileSize);
                }

                int tileIndex  = index * splitCount + i;
                var tileOffset = GetTileViewportOffset(tileIndex, split);
                SetTileViewport(tileOffset, tileSize);
                _dirShadowMatrices[tileIndex] = ConvertToAtlasMatrix(worldToLight: projectionMatrix * viewMatrix,
                                                                     tileOffset, split);
                _buffer.SetViewProjectionMatrices(viewMatrix, projectionMatrix);

                _buffer.SetGlobalDepthBias(0f, light.slopeScaleBias);
                ExecuteBuffer();
                _context.DrawShadows(ref shadowSettings);
                _buffer.SetGlobalDepthBias(0f, 0f);
            }
        }
Ejemplo n.º 16
0
    void RenderDirectionalShadows(int index, int split, int tileSize)
    {
        ShadowedDirectionalLight light = ShadowedDirectionalLights[index];
        var     shadowSettings         = new ShadowDrawingSettings(_cullingResults, light.visibleLightIndex);
        int     cascadeCount           = _settings.directional.cascadeCount;
        int     tileOffset             = index * cascadeCount;
        Vector3 ratios        = _settings.directional.CascadeRatios;
        float   cullingFactor = Mathf.Max(0f, 0.8f - _settings.directional.cascadeFade);

        for (int i = 0; i < cascadeCount; i++)
        {
            // 阴影贴图的原理是,从灯光的角度渲染场景,只存储深度信息,用结果标记出来,光线在击中某物体之前会传播多远
            // 但是定向光没有真实位置,我们要做的是找出与灯光方向匹配的视图/投影矩阵,并为我们提供一个裁剪空间立方体
            // 该立方体与包含可见光阴影的摄像机可见区域重合
            _cullingResults.ComputeDirectionalShadowMatricesAndCullingPrimitives(
                light.visibleLightIndex, i, cascadeCount, ratios, tileSize,
                light.nearPlaneOffset, out Matrix4x4 viewMatrix, out Matrix4x4 projectionMatrix,
                out ShadowSplitData splitData);
            // 避免对每个光源渲染相同的阴影投射器不止一次,如果可以保证从较小的级联中覆盖某些阴影投射器,就可以尝试从较大的级联中剔除掉
            // 某些阴影投射器
            splitData.shadowCascadeBlendCullingFactor = cullingFactor;
            shadowSettings.splitData = splitData;
            if (index == 0)
            {
                SetCascadeData(i, splitData.cullingSphere, tileSize);
                // Vector4 cullingSphere = splitData.cullingSphere;
            }
            int tileIndex = tileOffset + i;
            // SetTileViewport(index, split, tileSize);
            // dirShadowMatrices[index] = projectionMatrix * viewMatrix;
            dirShadowMatrices[tileIndex] =
                ConvertToAtlasMatrix(projectionMatrix * viewMatrix, SetTileViewport(tileIndex, split, tileSize), split);
            buffer.SetViewProjectionMatrices(viewMatrix, projectionMatrix);
            // buffer.SetGlobalDepthBias(500000f, 0f);
            // buffer.SetGlobalDepthBias(0f, 3f);
            buffer.SetGlobalDepthBias(0f, light.slopeScaleBias);
            ExecuteBuffer();
            _context.DrawShadows(ref shadowSettings);
            buffer.SetGlobalDepthBias(0f, 0f);
        }
    }
Ejemplo n.º 17
0
    private void RenderDirectionalShadows(int index, int split, int tileSize)
    {
        ShadowedDirectionalLight light          = shadowedDirectionalLights[index];
        ShadowDrawingSettings    shadowSettings = new ShadowDrawingSettings(cullingResults, light.visibleLightIndex)
        {
            useRenderingLayerMaskTest = true
        };

        int     cascadeCount = this.shadowSettings.directional.cascadeCount;
        int     tileOffset   = index * cascadeCount;
        Vector3 ratios       = this.shadowSettings.directional.CascadeRatios;

        float cullingFactor = Mathf.Max(0f, 0.8f - this.shadowSettings.directional.cascadeFade);
        float tileScale     = 1f / split;

        for (int i = 0; i < cascadeCount; ++i)
        {
            cullingResults.ComputeDirectionalShadowMatricesAndCullingPrimitives(
                light.visibleLightIndex, i, cascadeCount, ratios, tileSize, light.nearPlaneOffset, out Matrix4x4 viewMatrix,
                out Matrix4x4 projectionMatrix, out ShadowSplitData splitData);
            splitData.shadowCascadeBlendCullingFactor = cullingFactor;
            shadowSettings.splitData = splitData;
            int tileIndex = tileOffset + i;
            if (index == 0)
            {
                //Vector4 cullingSphere = splitData.cullingSphere;
                //cullingSphere.w *= cullingSphere.w;
                //cascadeCullingSpheres[i] = cullingSphere;

                SetCascadeData(i, splitData.cullingSphere, tileSize);
            }
            //SetTileViewport(index, split, tileSize);
            //dirShadowMatrices[index] = projectionMatrix * viewMatrix;
            dirShadowMatrices[tileIndex] = ConvertToAtlasMatrix(projectionMatrix * viewMatrix, SetTileViewport(tileIndex, split, tileSize), tileScale);
            buffer.SetViewProjectionMatrices(viewMatrix, projectionMatrix);
            buffer.SetGlobalDepthBias(0f, light.slopeScaleBias);
            ExecuteBuffer();
            context.DrawShadows(ref shadowSettings);
            buffer.SetGlobalDepthBias(0f, 0f);
        }
    }
Ejemplo n.º 18
0
    void RenderDirectionalShadows(int index, int tileSize)
    {
        ShadowedDirectionalLight light = ShadowedDirectionalLights[index];
        ///ShadowDrawingSettings built-in
        var shadowSettings =
            new ShadowDrawingSettings(cullingResults, light.visibleLightIndex);

        ///The idea of a shadow map is that we render the scene from the light's point of view,
        ///only storing the depth information.
        ///The result tells us how far the light travels before it hits something.
        cullingResults.ComputeDirectionalShadowMatricesAndCullingPrimitives(
            light.visibleLightIndex, 0, 1, Vector3.zero, tileSize, 0f,
            out Matrix4x4 viewMatrix, out Matrix4x4 projectionMatrix,
            out ShadowSplitData splitData
            );
        ///The split data contains information about how shadow-casting objects should be culled
        shadowSettings.splitData = splitData;
        buffer.SetViewProjectionMatrices(viewMatrix, projectionMatrix);
        ExecuteBuffer();
        context.DrawShadows(ref shadowSettings);
    }
Ejemplo n.º 19
0
    public Vector4 ReserveDirectioanlShadows(Light light, int visibleLightIndex)
    {
        if (ShadowedDirectionalLightCount < maxShadowedDirectionalLightCount &&
            light.shadows != LightShadows.None && light.shadowStrength > 0f //&&
            //cullingResults.GetShadowCasterBounds(visibleLightIndex, out Bounds b)
            )
        //the getshadowCasterBound will return false if the light does not effect any oject(can cast shadow) in shadow range
        {
            float maskChannel = -1;
            //we will decide wether to use the shadow mask depend on if the lights are using thi shadow mask
            LightBakingOutput lightBaking = light.bakingOutput;
            if (lightBaking.lightmapBakeType == LightmapBakeType.Mixed &&
                lightBaking.mixedLightingMode == MixedLightingMode.Shadowmask)
            {
                useShadowMask = true;
                maskChannel   = lightBaking.occlusionMaskChannel;
            }

            //Inform Shader the light does not affect anything, used for baked light attenuation
            if (!cullingResults.GetShadowCasterBounds(visibleLightIndex, out Bounds b))
            {
                return(new Vector4(-light.shadowStrength, 0f, maskChannel));
            }

            ShadowedDirectionalLights[ShadowedDirectionalLightCount] =
                new ShadowedDirectionalLight {
                visibleLightIndex = visibleLightIndex,
                slopScaleBias     = light.shadowBias,
                nearPlaneOffset   = light.shadowNearPlane
            };
            return(new Vector4(light.shadowStrength,
                               shadowSettings.directional.cascadeCount * ShadowedDirectionalLightCount++,
                               light.shadowNormalBias,
                               maskChannel));
        }
        else
        {
            return(new Vector4(0f, 0f, 0f, -1f));
        }
    }