Example #1
0
	private void RenderDirectionalShadow(CullingResults cull, int sunlightIndex, Light sunlight) {
		ResetRenderTarget(SunlightShadowmapId, true, false, 1, Color.black);
		
		var shadowSettings = new ShadowDrawingSettings(cull, sunlightIndex);
		if (!cull.ComputeDirectionalShadowMatricesAndCullingPrimitives(sunlightIndex, 0, 1, new Vector3(1, 0, 0), @params.sunlightParams.shadowResolution, sunlight.shadowNearPlane, out var viewMatrix, out var projectionMatrix, out var splitData)) {
			ExecuteCurrentBuffer();
			return;
		}
		
		shadowSettings.splitData = splitData;
		
		_currentBuffer.SetViewProjectionMatrices(viewMatrix, projectionMatrix);
		
		if (_reversedZBuffer) {
			projectionMatrix.m20 = -projectionMatrix.m20;
			projectionMatrix.m21 = -projectionMatrix.m21;
			projectionMatrix.m22 = -projectionMatrix.m22;
			projectionMatrix.m23 = -projectionMatrix.m23;
		}
		
		var scaleOffset = Matrix4x4.identity;
		scaleOffset.m00 = scaleOffset.m11 = scaleOffset.m22 = scaleOffset.m03 = scaleOffset.m13 = scaleOffset.m23 = 0.5f;
		
		var sunlightInverseVP = scaleOffset * (projectionMatrix * viewMatrix);
		
		_currentBuffer.SetGlobalMatrix(ShaderManager.SUNLIGHT_INVERSE_VP, sunlightInverseVP);
		
		ExecuteCurrentBuffer();
		
		_context.DrawShadows(ref shadowSettings);
	}
Example #2
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);
        }
    }
Example #3
0
    void RenderDirectionalShadows(int index, int split, int tileSize)
    {
        ShadowDirectionalLight light = ShadowDirectionalLights[index];
        var shadowSettings           = new ShadowDrawingSettings(cullingResults, light.visibleLightIndex)
        {
            useRenderingLayerMaskTest = true
        };
        int     cascadeCount = settings.directional.cascadeCount;
        int     tileOffset   = index * cascadeCount;
        Vector3 ratios       = settings.directional.CascadeRatios;
        //裁剪参数
        float cullingFactor = Mathf.Max(0f, 0.8f - settings.directional.cascadeFade);
        float tileScale     = 1f / split;

        //遍历Cascade的数量
        for (int i = 0; i < cascadeCount; i++)
        {
            //Debug.Log(light.nearPlaneOffset);
            //Unity
            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)
            {
                //裁剪球 判断片段在哪一级的Cascade里面 w为半径
                Vector4 cullingSphere = splitData.cullingSphere;
                SetCascadeData(i, splitData.cullingSphere, tileSize);
            }

            int tileIndex = tileOffset + i;
            //设置ViewPort大小
            //SetTileViewport(index, split, tileSize);
            //从世界空间到灯光阴影投影空间
            dirShadowMatrices[tileIndex] = ConvertToAtlasMatrix(projectionMatrix * viewMatrix, SetTileViewport(tileIndex, split, tileSize), tileScale);
            buffer.SetViewProjectionMatrices(viewMatrix, projectionMatrix);

            //球覆盖
            buffer.SetGlobalVectorArray(cascadeCullingSpheresId, cascadeCullingSpheres);
            //Cascade数据
            buffer.SetGlobalVectorArray(cascadeDataId, cascadeData);
            //转换物体到灯光空间
            buffer.SetGlobalMatrixArray(dirShadowMatricesId, dirShadowMatrices);
            buffer.SetGlobalDepthBias(0f, light.slopeScaleBias);
            ExecuteBuffer();
            context.DrawShadows(ref shadowSettings);
            buffer.SetGlobalDepthBias(0f, 0f);
        }
    }
Example #4
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);
        }
    }
Example #5
0
        public void RenderShadows(ScriptableRenderContext renderContext, CommandBuffer cmd, DrawShadowsSettings dss)
        {
            cmd.SetRenderTarget(identifier);
            cmd.SetGlobalVector(HDShaderIDs._ShadowAtlasSize, new Vector4(m_Width, m_Height, 1.0f / m_Width, 1.0f / m_Height));

            foreach (var shadowRequest in shadowRequests)
            {
                cmd.SetViewport(shadowRequest.atlasViewport);
                cmd.SetViewProjectionMatrices(shadowRequest.view, shadowRequest.projection);

                cmd.SetGlobalFloat(HDShaderIDs._ZClip, shadowRequest.zClip ? 1.0f : 0.0f);
                CoreUtils.DrawFullScreen(cmd, m_ClearMaterial, null, 0);

                dss.lightIndex = shadowRequest.lightIndex;
                dss.splitData  = shadowRequest.splitData;

                // TODO: remove this execute when DrawShadows will use a CommandBuffer
                renderContext.ExecuteCommandBuffer(cmd);
                cmd.Clear();

                renderContext.DrawShadows(ref dss);
            }

            cmd.SetGlobalFloat(HDShaderIDs._ZClip, 1.0f);   // Re-enable zclip globally
        }
Example #6
0
    void RenderShadows(ScriptableRenderContext context)
    {
        shadowBuffer.GetTemporaryRT(shadowMapId, 512, 512, 16, FilterMode.Bilinear, RenderTextureFormat.Depth);
        shadowMap            = RenderTexture.GetTemporary(512, 512, 16, RenderTextureFormat.Shadowmap);
        shadowMap.filterMode = FilterMode.Bilinear;
        shadowMap.wrapMode   = TextureWrapMode.Clamp;

        CoreUtils.SetRenderTarget(shadowBuffer, shadowMap, RenderBufferLoadAction.DontCare, RenderBufferStoreAction.Store, ClearFlag.Depth);
        shadowBuffer.BeginSample("Render Shadows");
        context.ExecuteCommandBuffer(shadowBuffer);
        shadowBuffer.Clear();

        Matrix4x4       viewMatrix, projectMatrix;
        ShadowSplitData splitData;

        cullingResults.ComputeSpotShadowMatricesAndCullingPrimitives(0, out viewMatrix, out projectMatrix, out splitData);
        shadowBuffer.SetViewProjectionMatrices(viewMatrix, projectMatrix);
        context.ExecuteCommandBuffer(shadowBuffer);

        // draw shadow
        var shadowSettings = new ShadowDrawingSettings(cullingResults, 0);

        context.DrawShadows(ref shadowSettings);

        shadowBuffer.EndSample("Render Shadows");
        context.ExecuteCommandBuffer(shadowBuffer);
        shadowBuffer.Clear();
    }
Example #7
0
    void RenderSpotShadow(ref ScriptableRenderContext context, ref CullingResults cullingResults, int shadowMapSize, int index, ref VisibleLight visibleLight)
    {
        if (shadowData.lights[index] == null)
        {
            return;
        }

        CoreUtils.SetRenderTarget(buffer, shadowData.shadowMaps, ClearFlag.Depth, 0, CubemapFace.Unknown, index);
        SubmitBuffer(ref context, buffer);

        if (shadowData.lights[index].cascades[0] == null)
        {
            return;
        }

        Rect tileViewport = new Rect(0, 0, shadowMapSize, shadowMapSize);

        buffer.SetViewport(new Rect(tileViewport));
        buffer.SetViewProjectionMatrices(shadowData.lights[index].cascades[0].viewMatrix, shadowData.lights[index].cascades[0].projectionMatrix);
        ShaderInput.SetShadowBias(buffer, visibleLight.light.shadowBias);
        SubmitBuffer(ref context, buffer);

        ShadowDrawingSettings shadowSettings = new ShadowDrawingSettings(cullingResults, index);

        shadowSettings.splitData = shadowData.lights[index].cascades[0].splitData;
        context.DrawShadows(ref shadowSettings);
    }
Example #8
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);
            }
        }
Example #9
0
    void RenderDirectionalShadow(ref ScriptableRenderContext context, ref CullingResults cullingResults, int shadowMapSize, int index, ref VisibleLight visibleLight)
    {
        if (shadowData.lights[index] == null)
        {
            return;
        }

        CoreUtils.SetRenderTarget(buffer, shadowData.shadowMaps, ClearFlag.Depth, 0, CubemapFace.Unknown, index);
        SubmitBuffer(ref context, buffer);

        for (int j = 0; j < 4; j++)
        {
            if (shadowData.lights[index].cascades[j] == null)
            {
                continue;
            }

            Rect tileViewport = new Rect(shadowData.lights[index].cascades[j].tileOffset.x * shadowData.lights[index].tileSize, shadowData.lights[index].cascades[j].tileOffset.y * shadowData.lights[index].tileSize, shadowData.lights[index].tileSize, shadowData.lights[index].tileSize);

            buffer.SetViewport(new Rect(tileViewport));
            buffer.EnableScissorRect(new Rect(tileViewport.x + 4f, tileViewport.y + 4f, shadowData.lights[index].tileSize - 8f, shadowData.lights[index].tileSize - 8f));
            buffer.SetViewProjectionMatrices(shadowData.lights[index].cascades[j].viewMatrix, shadowData.lights[index].cascades[j].projectionMatrix);
            ShaderInput.SetShadowBias(buffer, visibleLight.light.shadowBias);
            SubmitBuffer(ref context, buffer);

            ShadowDrawingSettings shadowSettings = new ShadowDrawingSettings(cullingResults, index);
            shadowSettings.splitData = shadowData.lights[index].cascades[j].splitData;
            context.DrawShadows(ref shadowSettings);
        }

        buffer.DisableScissorRect();
        SubmitBuffer(ref context, buffer);
    }
    private void RenderCascadedShadows(ScriptableRenderContext context)
    {
        float tileSize = shadowMapSize / 2;

        cascadedShadowMap = SetShadowRenderTarget();
        shadowBuffer.BeginSample("Render Main Shadows");

        context.ExecuteCommandBuffer(shadowBuffer);
        shadowBuffer.Clear();
        Light shadowLight = cull.visibleLights[0].light;

        shadowBuffer.SetGlobalFloat(
            shadowBiasID, shadowLight.shadowBias);
        var shadowSettings = new DrawShadowsSettings(cull, 0);
        var tileMatrix     = Matrix4x4.identity;

        tileMatrix.m00 = tileMatrix.m11 = 0.5f;

        for (int i = 0; i < shadowCascades; i++)
        {
            Matrix4x4       viewMatrix, projectionMatrix;
            ShadowSplitData splitData;
            cull.ComputeDirectionalShadowMatricesAndCullingPrimitives(
                0, i, shadowCascades, shadowCascadeSplit, (int)tileSize
                , shadowLight.shadowNearPlane,
                out viewMatrix, out projectionMatrix, out splitData);

            Vector2 tileOffset = ConfigureShadowTile(i, 2, tileSize);
            shadowBuffer.SetViewProjectionMatrices(viewMatrix, projectionMatrix);
            context.ExecuteCommandBuffer(shadowBuffer);
            shadowBuffer.Clear();

            cascadeCullingSpheres[i] = shadowSettings.splitData.cullingSphere = splitData.cullingSphere;
            //储存半径平方 用于比较
            cascadeCullingSpheres[i].w *= splitData.cullingSphere.w;
            context.DrawShadows(ref shadowSettings);
            CalculateWorldToShadowMatrix(ref viewMatrix, ref projectionMatrix
                                         , out worldToShadowCascadeMatrices[i]);
            tileMatrix.m03 = tileOffset.x * 0.5f;
            tileMatrix.m13 = tileOffset.y * 0.5f;
            worldToShadowCascadeMatrices[i] = tileMatrix * worldToShadowCascadeMatrices[i];
        }

        shadowBuffer.DisableScissorRect();
        shadowBuffer.SetGlobalTexture(cascadedShadowMapID, cascadedShadowMap);
        shadowBuffer.SetGlobalVectorArray(cascadeCullingSpheresID, cascadeCullingSpheres);
        shadowBuffer.SetGlobalMatrixArray(worldToShadowCascadeMatricesID, worldToShadowCascadeMatrices);
        float invShadowMapSize = 1f / shadowMapSize;

        shadowBuffer.SetGlobalVector(cascadedShadowMapSizedID
                                     , new Vector4(invShadowMapSize, invShadowMapSize, shadowMapSize, shadowMapSize));
        shadowBuffer.SetGlobalFloat(cascadedShadowStrengthID, shadowLight.shadowStrength);
        bool hard = shadowLight.shadows == LightShadows.Hard;

        CoreUtils.SetKeyword(shadowBuffer, cascadedShadowsHardKeyword, hard);
        CoreUtils.SetKeyword(shadowBuffer, cascadedShadowsSoftKeyword, !hard);
        shadowBuffer.EndSample("Render Main Shadows");
        context.ExecuteCommandBuffer(shadowBuffer);
        shadowBuffer.Clear();
    }
Example #11
0
    void RenderDirectionalShadows(int index, int split, int tileSize)
    {
        var light          = ShadowedDirectionalLights[index];
        var shadowSettings = new ShadowDrawingSettings(cullingResults, index);

        cullingResults.ComputeDirectionalShadowMatricesAndCullingPrimitives(
            light.VisibleLightIndex,
            0,
            1,
            Vector3.zero,
            tileSize,
            0f,
            out Matrix4x4 viewMatrix,
            out Matrix4x4 projMatrix,
            out ShadowSplitData shadowSplitData);

        shadowSettings.splitData = shadowSplitData;

        // SetTileViewport(index, split, tileSize);
        DirShadowMatrices[index] = ConvertToAtlasMatrix(
            projMatrix * viewMatrix,
            SetTileViewport(index, split, tileSize),
            split);

        buffer.SetGlobalMatrixArray(DirShadowMatricesID, DirShadowMatrices);
        buffer.SetViewProjectionMatrices(viewMatrix, projMatrix);
        ExecuteBuffer();
        context.DrawShadows(ref shadowSettings);
    }
Example #12
0
 public void DrawShadow(ScriptableRenderContext context, CommandBuffer cmd)
 {
     if (!RenderShadow)
     {
         return;
     }
     context.DrawShadows(ref m_SadowSetting);
 }
Example #13
0
    void RenderOneDirectionalShadow(int lightIdx, int tileSplitFactor)
    {
        ShadowedLight shadowedLight      = _shadowedDirLights[lightIdx];
        int           cascadeSplitFactor = _shadowSetting.directional.cascadeCount > 1 ? 2 : 1;
        int           tileSize           = (int)_shadowSetting.directional.atlasSize / tileSplitFactor;
        int           cascadeSize        = (int)_shadowSetting.directional.atlasSize / (tileSplitFactor * cascadeSplitFactor);
        int           visibleIndex       = shadowedLight.visibleIndex;

        _shadowMapSizes.x = cascadeSize;

        _cmdBuffer.SetGlobalDepthBias(0, shadowedLight.light.shadowBias);
        for (int cascadeIdx = 0; cascadeIdx < _shadowSetting.directional.cascadeCount; cascadeIdx++)
        {
            _cullResults.ComputeDirectionalShadowMatricesAndCullingPrimitives(visibleIndex,
                                                                              cascadeIdx,
                                                                              _shadowSetting.directional.cascadeCount,
                                                                              _shadowSetting.directional.cascadeSplitRatio,
                                                                              cascadeSize,
                                                                              shadowedLight.light.shadowNearPlane,
                                                                              out Matrix4x4 viewMatrix,
                                                                              out Matrix4x4 projMatrix,
                                                                              out ShadowSplitData shadowSplitData);
            _cmdBuffer.SetViewProjectionMatrices(viewMatrix, projMatrix);

            Vector2 tileOffset     = new Vector2(lightIdx % 2, lightIdx / 2);
            Vector2 cascadeOffset  = new Vector2(cascadeIdx % 2, cascadeIdx / 2);
            Rect    viewPortOffset = new Rect(tileOffset.x * tileSize + cascadeOffset.x * cascadeSize, tileOffset.y * tileSize + cascadeOffset.y * cascadeSize, cascadeSize, cascadeSize);
            _cmdBuffer.SetViewport(viewPortOffset);
            ExecuteCommandBuffer();

            _dirShadowMatrixs[lightIdx * MAX_NUM_DIRECTIONAL_CASCADES + cascadeIdx] = ShadowMatrixToAtlasTileMatrix(projMatrix * viewMatrix, viewPortOffset, (int)_shadowSetting.directional.atlasSize);
            if (lightIdx == 0)   // all directional light share the same cascade culling spheres
            {
                _dirCascadeCullingSpheres[cascadeIdx] = shadowSplitData.cullingSphere;
            }

            ShadowDrawingSettings shadowDrawSetting = new ShadowDrawingSettings(_cullResults, visibleIndex)
            {
                splitData = shadowSplitData
            };
            _srContext.DrawShadows(ref shadowDrawSetting);
        }
        _cmdBuffer.SetGlobalDepthBias(0, 0);
    }
    private void shadow_pass(ref CullResults cull, ref ScriptableRenderContext context)
    {
        int     shadowLightIndex            = 0;
        int     cascadeIdx                  = 0;
        int     m_ShadowCasterCascadesCount = 1;
        Vector3 directionalLightCascades    = new Vector3(1.0f, 0.0f, 0.0f);
        int     shadowNearPlaneOffset       = 0;

        Matrix4x4 view;
        Matrix4x4 proj;

        foreach (var light in cull.visibleLights)
        {
            if (light.lightType == LightType.Directional)
            {
                DrawShadowsSettings sss = new DrawShadowsSettings(cull, shadowLightIndex);

                var success = cull.ComputeDirectionalShadowMatricesAndCullingPrimitives(shadowLightIndex,
                                                                                        cascadeIdx, m_ShadowCasterCascadesCount, directionalLightCascades,
                                                                                        shadowResolution, shadowNearPlaneOffset, out view, out proj,
                                                                                        out sss.splitData);

                //view 光源的视空间
                //proj 光源的裁剪空间
                if (success)
                {
                    cmd.Clear();
                    cmd.name = "clear shadow map";
                    cmd.SetRenderTarget(_ScreenSpaceShadowMapId);
                    cmd.ClearRenderTarget(true, true, Color.black);
                    context.ExecuteCommandBuffer(cmd);


                    cmd.Clear();
                    cmd.name = "create shadow map";
                    cmd.SetViewport(new Rect(0, 0, shadowResolution, shadowResolution));
                    cmd.SetViewProjectionMatrices(view, proj);
                    context.ExecuteCommandBuffer(cmd);

                    context.DrawShadows(ref sss);
                    context.ExecuteCommandBuffer(cmd);
                }

                cmd.Clear();
                if (SystemInfo.usesReversedZBuffer)
                {
                    //Debug.Log("usesReversedZBuffer ");
                }
                cmd.SetGlobalMatrix(_mId, proj * view);
                context.ExecuteCommandBuffer(cmd);
            }

            shadowLightIndex++;
        }
    }
Example #15
0
        static void RenderShadows(RenderShadowsParameters parameters,
                                  RTHandle atlasRenderTexture,
                                  ShadowDrawingSettings shadowDrawSettings,
                                  ScriptableRenderContext renderContext,
                                  CommandBuffer cmd)
        {
            cmd.SetRenderTarget(atlasRenderTexture, RenderBufferLoadAction.DontCare, RenderBufferStoreAction.Store);
            cmd.SetGlobalVector(parameters.atlasSizeShaderID, new Vector4(atlasRenderTexture.rt.width, atlasRenderTexture.rt.height, 1.0f / atlasRenderTexture.rt.width, 1.0f / atlasRenderTexture.rt.height));

            // Clear the whole atlas to avoid garbage outside of current request when viewing it.
            if (parameters.debugClearAtlas)
            {
                CoreUtils.DrawFullScreen(cmd, parameters.clearMaterial, null, 0);
            }

            var hdrp = RenderPipelineManager.currentPipeline as HDRenderPipeline;

            foreach (var shadowRequest in parameters.shadowRequests)
            {
                if (shadowRequest.shouldUseCachedShadow)
                {
                    continue;
                }

                cmd.SetGlobalDepthBias(1.0f, shadowRequest.slopeBias);
                cmd.SetViewport(shadowRequest.atlasViewport);

                cmd.SetGlobalFloat(HDShaderIDs._ZClip, shadowRequest.zClip ? 1.0f : 0.0f);
                CoreUtils.DrawFullScreen(cmd, parameters.clearMaterial, null, 0);

                shadowDrawSettings.lightIndex = shadowRequest.lightIndex;
                shadowDrawSettings.splitData  = shadowRequest.splitData;

                // Setup matrices for shadow rendering:
                Matrix4x4 viewProjection = shadowRequest.deviceProjectionYFlip * shadowRequest.view;
                cmd.SetGlobalMatrix(HDShaderIDs._ViewMatrix, shadowRequest.view);
                cmd.SetGlobalMatrix(HDShaderIDs._InvViewMatrix, shadowRequest.view.inverse);
                cmd.SetGlobalMatrix(HDShaderIDs._ProjMatrix, shadowRequest.deviceProjectionYFlip);
                cmd.SetGlobalMatrix(HDShaderIDs._InvProjMatrix, shadowRequest.deviceProjectionYFlip.inverse);
                cmd.SetGlobalMatrix(HDShaderIDs._ViewProjMatrix, viewProjection);
                cmd.SetGlobalMatrix(HDShaderIDs._InvViewProjMatrix, viewProjection.inverse);
                cmd.SetGlobalVectorArray(HDShaderIDs._ShadowClipPlanes, shadowRequest.frustumPlanes);

                // TODO: remove this execute when DrawShadows will use a CommandBuffer
                renderContext.ExecuteCommandBuffer(cmd);
                cmd.Clear();

                renderContext.DrawShadows(ref shadowDrawSettings);

                hdrp?.InvokeShadowMapRender(cmd, shadowRequest.worldTexelSize);
            }
            cmd.SetGlobalFloat(HDShaderIDs._ZClip, 1.0f);   // Re-enable zclip globally
            cmd.SetGlobalDepthBias(0.0f, 0.0f);             // Reset depth bias.
        }
Example #16
0
    void RenderPointShadows(int index, int split, int tileSize)
    {
        ShadowedOtherLight light = shadowedOtherLights[index];
        var shadowSettings       =
            new ShadowDrawingSettings(cullingResults, light.visibleLightIndex)
        {
            useRenderingLayerMaskTest = true
        };

        float texelSize  = 2f / tileSize;
        float filterSize = texelSize * ((float)settings.other.filter + 1f);
        float bias       = light.normalBias * filterSize * 1.4142136f;
        float tileScale  = 1f / split;
        float fovBias    = Mathf.Atan(1f + bias + filterSize) * Mathf.Rad2Deg * 2f - 90f;

        for (int i = 0; i < 6; i++)
        {
            cullingResults.ComputePointShadowMatricesAndCullingPrimitives(
                light.visibleLightIndex, (CubemapFace)i, fovBias,
                out Matrix4x4 viewMatrix, out Matrix4x4 projectionMatrix,
                out ShadowSplitData splitData
                );
            viewMatrix.m11 = -viewMatrix.m11;
            viewMatrix.m12 = -viewMatrix.m12;
            viewMatrix.m13 = -viewMatrix.m13;

            shadowSettings.splitData = splitData;
            int     tileIndex = index + i;
            Vector2 offset    = SetTileViewport(tileIndex, split, tileSize);
            SetOtherTileData(tileIndex, offset, tileScale, bias);
            otherShadowMatrices[tileIndex] = ConvertToAtlasMatrix(
                projectionMatrix * viewMatrix, offset, tileScale
                );

            buffer.SetViewProjectionMatrices(viewMatrix, projectionMatrix);
            buffer.SetGlobalDepthBias(0f, light.slopeScaleBias);
            ExecuteBuffer();
            context.DrawShadows(ref shadowSettings);
            buffer.SetGlobalDepthBias(0f, 0f);
        }
    }
Example #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);
        }
    }
Example #18
0
        private void RenderDirectionalShadows(int index, int tileSize)
        {
            ShadowDirectionalLight light = _shadowDirectionalLights[index];
            var shadowDrawSettings       = new ShadowDrawingSettings(_cullingResults, light.visibleLightIndex);

            _cullingResults.ComputeDirectionalShadowMatricesAndCullingPrimitives(light.visibleLightIndex, 0, 1,
                                                                                 Vector3.zero, tileSize, 0f, out Matrix4x4 viewMatrix, out Matrix4x4 projectionMatrix,
                                                                                 out ShadowSplitData splitData);
            shadowDrawSettings.splitData = splitData;
            _buffer.SetViewProjectionMatrices(viewMatrix, projectionMatrix);
            ExecuteBuffer();
            _context.DrawShadows(ref shadowDrawSettings);
        }
Example #19
0
 public static void RenderShadowSlice(CommandBuffer cmd, ref ScriptableRenderContext context,
                                      ref ShadowSliceData shadowSliceData, ref ShadowDrawingSettings settings,
                                      Matrix4x4 proj, Matrix4x4 view)
 {
     cmd.SetViewport(new Rect(shadowSliceData.offsetX, shadowSliceData.offsetY, shadowSliceData.resolution, shadowSliceData.resolution));
     cmd.SetViewProjectionMatrices(view, proj);
     context.ExecuteCommandBuffer(cmd);
     cmd.Clear();
     context.DrawShadows(ref settings);
     cmd.DisableScissorRect();
     context.ExecuteCommandBuffer(cmd);
     cmd.Clear();
 }
Example #20
0
        private void RenderShadowSlice(ref ScriptableRenderContext context, int cascadeIndex,
                                       Matrix4x4 proj, Matrix4x4 view, DrawShadowsSettings settings)
        {
            var buffer = CommandBufferPool.Get("Prepare Shadowmap Slice");

            buffer.SetViewport(new Rect(m_ShadowSlices[cascadeIndex].atlasX, m_ShadowSlices[cascadeIndex].atlasY,
                                        m_ShadowSlices[cascadeIndex].shadowResolution, m_ShadowSlices[cascadeIndex].shadowResolution));
            buffer.SetViewProjectionMatrices(view, proj);
            context.ExecuteCommandBuffer(buffer);

            context.DrawShadows(ref settings);
            CommandBufferPool.Release(buffer);
        }
Example #21
0
    void RenderShadow(ScriptableRenderContext context)
    {
        shadowMap            = RenderTexture.GetTemporary(this.shadowMapSize, this.shadowMapSize, 16, RenderTextureFormat.Shadowmap);
        shadowMap.filterMode = FilterMode.Bilinear;
        shadowMap.wrapMode   = TextureWrapMode.Clamp;

        CoreUtils.SetRenderTarget(shadowBuffer, shadowMap,
                                  RenderBufferLoadAction.DontCare, RenderBufferStoreAction.Store, ClearFlag.Depth);
        shadowBuffer.BeginSample("Render Shadow");

        // Set View matrix and projection matrix
        Matrix4x4       viewMatrix, projMatrix;
        ShadowSplitData shadowSplitData;

        this.cull.ComputeSpotShadowMatricesAndCullingPrimitives(0, out viewMatrix, out projMatrix, out shadowSplitData);
        shadowBuffer.SetViewProjectionMatrices(viewMatrix, projMatrix);
        shadowBuffer.SetGlobalFloat(shadowBiasID, cull.visibleLights[0].light.shadowBias);

        context.ExecuteCommandBuffer(shadowBuffer);
        shadowBuffer.Clear();

        // Draw Shadow Casters
        var shadowSetting = new DrawShadowsSettings(cull, 0);

        context.DrawShadows(ref shadowSetting);

        // Set Shadow map and shadow space matrix
        if (SystemInfo.usesReversedZBuffer)
        {
            projMatrix.m20 = -projMatrix.m20;
            projMatrix.m21 = -projMatrix.m21;
            projMatrix.m22 = -projMatrix.m22;
            projMatrix.m23 = -projMatrix.m23;
        }

        Matrix4x4 scaleOffset = Matrix4x4.identity;

        scaleOffset.m00 = scaleOffset.m11 = scaleOffset.m22 = 0.5f;
        scaleOffset.m03 = scaleOffset.m13 = scaleOffset.m23 = 0.5f;
        Matrix4x4 worldToShadowMatrix = scaleOffset * projMatrix * viewMatrix;

        shadowBuffer.SetGlobalMatrix(worldToShadowMatrixID, worldToShadowMatrix);
        shadowBuffer.SetGlobalTexture(shadowMapID, shadowMap);
        shadowBuffer.SetGlobalFloat(shadowStrengthID, cull.visibleLights[0].light.shadowStrength);


        shadowBuffer.EndSample("Render Shadow");
        context.ExecuteCommandBuffer(shadowBuffer);
        shadowBuffer.Clear();
    }
Example #22
0
        private void RenderShadowSlice(ref ScriptableRenderContext context, Vector3 lightDir, int cascadeIndex,
                                       Matrix4x4 proj, Matrix4x4 view, DrawShadowsSettings settings)
        {
            var buffer = new CommandBuffer()
            {
                name = "Prepare Shadowmap Slice"
            };

            buffer.SetViewport(new Rect(m_ShadowSlices[cascadeIndex].atlasX, m_ShadowSlices[cascadeIndex].atlasY,
                                        m_ShadowSlices[cascadeIndex].shadowResolution, m_ShadowSlices[cascadeIndex].shadowResolution));
            buffer.SetViewProjectionMatrices(view, proj);
            context.ExecuteCommandBuffer(buffer);
            buffer.Dispose();

            context.DrawShadows(ref settings);
        }
        private void RenderShadowSlice(CommandBuffer cmd, ref ScriptableRenderContext context, int cascadeIndex,
                                       Matrix4x4 proj, Matrix4x4 view, DrawShadowsSettings settings)
        {
            cmd.SetViewport(new Rect(m_ShadowSlices[cascadeIndex].atlasX, m_ShadowSlices[cascadeIndex].atlasY,
                                     m_ShadowSlices[cascadeIndex].shadowResolution, m_ShadowSlices[cascadeIndex].shadowResolution));
            cmd.EnableScissorRect(new Rect(m_ShadowSlices[cascadeIndex].atlasX + 4, m_ShadowSlices[cascadeIndex].atlasY + 4,
                                           m_ShadowSlices[cascadeIndex].shadowResolution - 8, m_ShadowSlices[cascadeIndex].shadowResolution - 8));

            cmd.SetViewProjectionMatrices(view, proj);
            context.ExecuteCommandBuffer(cmd);
            cmd.Clear();
            context.DrawShadows(ref settings);
            cmd.DisableScissorRect();
            context.ExecuteCommandBuffer(cmd);
            cmd.Clear();
        }
Example #24
0
        public static void RenderShadowSlice(CommandBuffer cmd, ref ScriptableRenderContext context,
                                             ref ShadowSliceData shadowSliceData, ref ShadowDrawingSettings settings,
                                             Matrix4x4 proj, Matrix4x4 view, Vector4 shadowBias, VisibleLight shadowLight, int cascadeIndex)
        {
            cmd.SetViewport(new Rect(shadowSliceData.offsetX, shadowSliceData.offsetY, shadowSliceData.resolution, shadowSliceData.resolution));
            cmd.EnableScissorRect(new Rect(shadowSliceData.offsetX + 4, shadowSliceData.offsetY + 4, shadowSliceData.resolution - 8, shadowSliceData.resolution - 8));

            cmd.SetViewProjectionMatrices(view, proj);
            context.ExecuteCommandBuffer(cmd);
            cmd.Clear();
            context.DrawShadows(ref settings);
            CustomRenderShadowSlice?.Invoke(cmd, GL.GetGPUProjectionMatrix(proj, true) * view, shadowBias, shadowLight, cascadeIndex);
            cmd.DisableScissorRect();
            context.ExecuteCommandBuffer(cmd);
            cmd.Clear();
        }
    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);
    }
Example #26
0
        public void RenderShadows(ScriptableRenderContext renderContext, CommandBuffer cmd, ShadowDrawingSettings dss)
        {
            if (m_ShadowRequests.Count == 0)
            {
                return;
            }

            cmd.SetRenderTarget(identifier);
            cmd.SetGlobalVector(m_AtlasSizeShaderID, new Vector4(width, height, 1.0f / width, 1.0f / height));

            if (m_LightingDebugSettings.clearShadowAtlas)
            {
                CoreUtils.DrawFullScreen(cmd, m_ClearMaterial, null, 0);
            }

            foreach (var shadowRequest in m_ShadowRequests)
            {
                cmd.SetViewport(shadowRequest.atlasViewport);

                cmd.SetGlobalFloat(HDShaderIDs._ZClip, shadowRequest.zClip ? 1.0f : 0.0f);
                if (!m_LightingDebugSettings.clearShadowAtlas)
                {
                    CoreUtils.DrawFullScreen(cmd, m_ClearMaterial, null, 0);
                }

                dss.lightIndex = shadowRequest.lightIndex;
                dss.splitData  = shadowRequest.splitData;

                // Setup matrices for shadow rendering:
                Matrix4x4 viewProjection = shadowRequest.deviceProjectionYFlip * shadowRequest.view;
                cmd.SetGlobalMatrix(HDShaderIDs._ViewMatrix, shadowRequest.view);
                cmd.SetGlobalMatrix(HDShaderIDs._InvViewMatrix, shadowRequest.view.inverse);
                cmd.SetGlobalMatrix(HDShaderIDs._ProjMatrix, shadowRequest.deviceProjectionYFlip);
                cmd.SetGlobalMatrix(HDShaderIDs._InvProjMatrix, shadowRequest.deviceProjectionYFlip.inverse);
                cmd.SetGlobalMatrix(HDShaderIDs._ViewProjMatrix, viewProjection);
                cmd.SetGlobalMatrix(HDShaderIDs._InvViewProjMatrix, viewProjection.inverse);
                cmd.SetGlobalVectorArray(HDShaderIDs._ShadowClipPlanes, shadowRequest.frustumPlanes);

                // TODO: remove this execute when DrawShadows will use a CommandBuffer
                renderContext.ExecuteCommandBuffer(cmd);
                cmd.Clear();

                renderContext.DrawShadows(ref dss);
            }

            cmd.SetGlobalFloat(HDShaderIDs._ZClip, 1.0f);   // Re-enable zclip globally
        }
    private bool RenderShadowMaps(ref ScriptableRenderContext context, ref CullingResults cullingResults, ref Matrix4x4 worldToShadowMatrix)
    {
        if (cullingResults.visibleLights.Length == 0)
        {
            return(false);
        }

        int lightIndex = 0; // Just use first light (index 0) for shadows and assume it's a directional light

        bool needToRender = cullingResults.ComputeDirectionalShadowMatricesAndCullingPrimitives(lightIndex, 0, 1, Vector3.forward, 1024, cullingResults.visibleLights[0].light.shadowNearPlane, out Matrix4x4 viewMatrix, out Matrix4x4 projMatrix, out ShadowSplitData shadowSplitData);

        if (!needToRender)
        {
            return(false);
        }

        CommandBuffer cb = new CommandBuffer();

        cb.name = "Set up shadow data";
        cb.SetRenderTarget(m_ShadowMap);
        cb.ClearRenderTarget(true, true, Color.clear);
        cb.SetViewProjectionMatrices(viewMatrix, projMatrix);
        context.ExecuteCommandBuffer(cb);

        ShadowDrawingSettings shadowDrawSettings = new ShadowDrawingSettings(cullingResults, lightIndex);

        shadowDrawSettings.splitData = shadowSplitData;

        context.DrawShadows(ref shadowDrawSettings);

        if (SystemInfo.usesReversedZBuffer)
        {
            projMatrix.m20 = -projMatrix.m20;
            projMatrix.m21 = -projMatrix.m21;
            projMatrix.m22 = -projMatrix.m22;
            projMatrix.m23 = -projMatrix.m23;
        }

        var scaleOffset = Matrix4x4.TRS(
            Vector3.one * 0.5f, Quaternion.identity, Vector3.one * 0.5f
            );

        worldToShadowMatrix =
            scaleOffset * (projMatrix * viewMatrix);

        return(true);
    }
Example #28
0
        public static void RenderShadowSlice(CommandBuffer cmd, ref ScriptableRenderContext context,
                                             ref ShadowSliceData shadowSliceData, ref ShadowDrawingSettings settings,
                                             Matrix4x4 proj, Matrix4x4 view)
        {
            cmd.SetGlobalDepthBias(1.0f, 2.5f); // these values match HDRP defaults (see https://github.com/Unity-Technologies/Graphics/blob/9544b8ed2f98c62803d285096c91b44e9d8cbc47/com.unity.render-pipelines.high-definition/Runtime/Lighting/Shadow/HDShadowAtlas.cs#L197 )

            cmd.SetViewport(new Rect(shadowSliceData.offsetX, shadowSliceData.offsetY, shadowSliceData.resolution, shadowSliceData.resolution));
            cmd.SetViewProjectionMatrices(view, proj);
            context.ExecuteCommandBuffer(cmd);
            cmd.Clear();
            context.DrawShadows(ref settings);
            cmd.DisableScissorRect();
            context.ExecuteCommandBuffer(cmd);
            cmd.Clear();

            cmd.SetGlobalDepthBias(0.0f, 0.0f); // Restore previous depth bias values
        }
Example #29
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);
        }
    }
        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);
            }
        }