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();
    }
示例#2
0
        void RenderAdditionalShadowmapAtlas(ref ScriptableRenderContext context, ref CullResults cullResults, ref LightData lightData, ref ShadowData shadowData)
        {
            List <VisibleLight> visibleLights = lightData.visibleLights;

            bool          additionalLightHasSoftShadows = false;
            CommandBuffer cmd = CommandBufferPool.Get(k_RenderAdditionalLightShadows);

            using (new ProfilingSample(cmd, k_RenderAdditionalLightShadows))
            {
                int shadowmapWidth  = shadowData.additionalLightsShadowmapWidth;
                int shadowmapHeight = shadowData.additionalLightsShadowmapHeight;

                m_AdditionalLightsShadowmapTexture = RenderTexture.GetTemporary(shadowmapWidth, shadowmapHeight,
                                                                                k_ShadowmapBufferBits, m_AdditionalShadowmapFormat);
                m_AdditionalLightsShadowmapTexture.filterMode = FilterMode.Bilinear;
                m_AdditionalLightsShadowmapTexture.wrapMode   = TextureWrapMode.Clamp;

                SetRenderTarget(cmd, m_AdditionalLightsShadowmapTexture, RenderBufferLoadAction.DontCare, RenderBufferStoreAction.Store,
                                ClearFlag.Depth, Color.black, TextureDimension.Tex2D);

                for (int i = 0; i < m_AdditionalShadowCastingLightIndices.Count; ++i)
                {
                    int          shadowLightIndex = m_AdditionalShadowCastingLightIndices[i];
                    VisibleLight shadowLight      = visibleLights[shadowLightIndex];

                    if (m_AdditionalShadowCastingLightIndices.Count > 1)
                    {
                        ShadowUtils.ApplySliceTransform(ref m_AdditionalLightSlices[i], shadowmapWidth, shadowmapHeight);
                    }

                    var     settings   = new DrawShadowsSettings(cullResults, shadowLightIndex);
                    Vector4 shadowBias = ShadowUtils.GetShadowBias(ref shadowLight, shadowLightIndex,
                                                                   ref shadowData, m_AdditionalLightSlices[i].projectionMatrix, m_AdditionalLightSlices[i].resolution);
                    ShadowUtils.SetupShadowCasterConstantBuffer(cmd, ref shadowLight, shadowBias);
                    ShadowUtils.RenderShadowSlice(cmd, ref context, ref m_AdditionalLightSlices[i], ref settings, m_AdditionalLightSlices[i].projectionMatrix, m_AdditionalLightSlices[i].viewMatrix);
                    additionalLightHasSoftShadows |= shadowLight.light.shadows == LightShadows.Soft;
                }

                SetupAdditionalLightsShadowReceiverConstants(cmd, ref shadowData);
            }

            // We share soft shadow settings for main light and additional lights to save keywords.
            // So we check here if pipeline supports soft shadows and either main light or any additional light has soft shadows
            // to enable the keyword.
            // TODO: In PC and Consoles we can upload shadow data per light and branch on shader. That will be more likely way faster.
            bool mainLightHasSoftShadows = shadowData.supportsMainLightShadows &&
                                           lightData.mainLightIndex != -1 &&
                                           visibleLights[lightData.mainLightIndex].light.shadows == LightShadows.Soft;

            bool softShadows = shadowData.supportsSoftShadows && (mainLightHasSoftShadows || additionalLightHasSoftShadows);

            CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.AdditionalLightShadows, true);
            CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.SoftShadows, softShadows);
            context.ExecuteCommandBuffer(cmd);
            CommandBufferPool.Release(cmd);
        }
    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++;
        }
    }
示例#4
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);
        }
示例#5
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();
    }
        private void RenderShadowSlice(CommandBuffer cmd, ref ScriptableRenderContext context, ref ShadowSliceData shadowSliceData,
                                       Matrix4x4 proj, Matrix4x4 view, DrawShadowsSettings settings)
        {
            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);
            cmd.DisableScissorRect();
            context.ExecuteCommandBuffer(cmd);
            cmd.Clear();
        }
示例#7
0
        public void RenderShadows(ScriptableRenderContext renderContext, CommandBuffer cmd, CullResults cullResults)
        {
            // Avoid to do any commands if there is no shadow to draw
            if (m_ShadowRequests.Count == 0)
            {
                return;
            }

            // TODO remove DrawShadowSettings, lightIndex and splitData when scriptable culling is available
            DrawShadowsSettings dss = new DrawShadowsSettings(cullResults, 0);

            // Clear atlas render targets and draw shadows
            m_Atlas.RenderShadows(renderContext, cmd, dss);
            m_CascadeAtlas.RenderShadows(renderContext, cmd, dss);
        }
        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();
        }
示例#9
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);
        }
示例#10
0
        public override void Render(ScriptableRenderContext renderContext, Camera[] cameras)
        {
            base.Render(renderContext, cameras);

            foreach (var camera in cameras)
            {
                ScriptableCullingParameters cullingParams;
                if (!CullResults.GetCullingParameters(camera, out cullingParams))
                {
                    continue;
                }

                cullingParams.shadowDistance = Mathf.Min(2000, camera.farClipPlane);

                CullResults cull = CullResults.Cull(ref cullingParams, renderContext);

                renderContext.SetupCameraProperties(camera);

                var cmd = new CommandBuffer();
                cmd.ClearRenderTarget(true, false, m_ClearColor);
                renderContext.ExecuteCommandBuffer(cmd);

                cmd.Release();

                var settings = new DrawRendererSettings(camera, new ShaderPassName("basic"));
                settings.sorting.flags = SortFlags.CommonOpaque;

                var filterSettings = new FilterRenderersSettings(true)
                {
                    renderQueueRange = RenderQueueRange.opaque
                };
                renderContext.DrawRenderers(cull.visibleRenderers, ref settings, filterSettings);

                var shadowSettings = new DrawShadowsSettings(cull, 0);
                //renderContext.DrawShadows(ref shadowSettings);

                renderContext.DrawSkybox(camera);

                settings.sorting.flags          = SortFlags.CommonTransparent;
                filterSettings.renderQueueRange = RenderQueueRange.transparent;
                renderContext.DrawRenderers(cull.visibleRenderers, ref settings, filterSettings);
            }
            renderContext.Submit();
        }
示例#11
0
        void RenderMainLightCascadeShadowmap(ref ScriptableRenderContext context, ref CullResults cullResults, ref LightData lightData, ref ShadowData shadowData)
        {
            int shadowLightIndex = lightData.mainLightIndex;

            if (shadowLightIndex == -1)
            {
                return;
            }

            VisibleLight shadowLight = lightData.visibleLights[shadowLightIndex];

            CommandBuffer cmd = CommandBufferPool.Get(k_RenderMainLightShadowmapTag);

            using (new ProfilingSample(cmd, k_RenderMainLightShadowmapTag))
            {
                var settings = new DrawShadowsSettings(cullResults, shadowLightIndex);

                m_MainLightShadowmapTexture = RenderTexture.GetTemporary(shadowData.mainLightShadowmapWidth,
                                                                         shadowData.mainLightShadowmapHeight, k_ShadowmapBufferBits, m_ShadowmapFormat);
                m_MainLightShadowmapTexture.filterMode = FilterMode.Bilinear;
                m_MainLightShadowmapTexture.wrapMode   = TextureWrapMode.Clamp;
                SetRenderTarget(cmd, m_MainLightShadowmapTexture, RenderBufferLoadAction.DontCare,
                                RenderBufferStoreAction.Store, ClearFlag.Depth, Color.black, TextureDimension.Tex2D);

                for (int cascadeIndex = 0; cascadeIndex < m_ShadowCasterCascadesCount; ++cascadeIndex)
                {
                    settings.splitData.cullingSphere = m_CascadeSplitDistances[cascadeIndex];
                    Vector4 shadowBias = ShadowUtils.GetShadowBias(ref shadowLight, shadowLightIndex, ref shadowData, m_CascadeSlices[cascadeIndex].projectionMatrix, m_CascadeSlices[cascadeIndex].resolution);
                    ShadowUtils.SetupShadowCasterConstantBuffer(cmd, ref shadowLight, shadowBias);
                    ShadowUtils.RenderShadowSlice(cmd, ref context, ref m_CascadeSlices[cascadeIndex],
                                                  ref settings, m_CascadeSlices[cascadeIndex].projectionMatrix, m_CascadeSlices[cascadeIndex].viewMatrix);
                }

                SetupMainLightShadowReceiverConstants(cmd, ref shadowData, shadowLight);
            }

            CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.MainLightShadows, true);
            CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.MainLightShadowCascades, shadowData.mainLightShadowCascadesCount > 1);
            CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.SoftShadows, shadowLight.light.shadows == LightShadows.Soft && shadowData.supportsSoftShadows);
            context.ExecuteCommandBuffer(cmd);
            CommandBufferPool.Release(cmd);
        }
    private void RenderShadows(ScriptableRenderContext context)
    {
        int split;

        if (shadowTileCount <= 1)
        {
            split = 1;
        }
        else if (shadowTileCount <= 4)
        {
            split = 2;
        }
        else if (shadowTileCount <= 9)
        {
            split = 3;
        }
        else
        {
            split = 4;
        }

        //虽然也可以用tex2DArray 但是不支持一些老机型手机
        //所以这里用图片分割成4*4块
        float tileSize  = shadowMapSize / split;
        float tileScale = 1f / split;

        globalShadowData.x = tileScale;

        shadowMap = SetShadowRenderTarget();

        shadowBuffer.BeginSample("Render Addition Shadows");
        context.ExecuteCommandBuffer(shadowBuffer);
        shadowBuffer.Clear();


        int  tileIndex   = 0;
        bool hardShadows = false;
        bool softShadows = false;

        for (int i = mainLightExists ? 1 : 0; i < cull.visibleLights.Count && i < maxVisibleLights; i++)
        {
            //剔除没有强度的 或者不需要的
            if (shadowData[i].x <= 0f)
            {
                continue;
            }

            Matrix4x4       viewMatrix, projectionMatrix;
            ShadowSplitData splitData;

            //是否能生成有效的矩阵 如果没有 x=0 表示不启用阴影
            bool validShadows;

            if (shadowData[i].z > 0f)
            {
                //参数 1:灯光index  2:cascadeIndex  3:cascadeCount   4:cascade 分级距离
                //5: 分辨率   6:nearPlane 如果太近不画
                validShadows = cull.ComputeDirectionalShadowMatricesAndCullingPrimitives(
                    i, 0, 1, Vector3.right, (int)tileSize
                    , cull.visibleLights[i].light.shadowNearPlane
                    , out viewMatrix, out projectionMatrix, out splitData);
            }
            else
            {
                validShadows = cull.ComputeSpotShadowMatricesAndCullingPrimitives(
                    i, out viewMatrix, out projectionMatrix, out splitData);
            }

            if (!validShadows)
            {
                shadowData[i].x = 0f;
                continue;
            }

            //设置渲染到贴图上的区域(起始位置和大小)
            Vector2 tileOffset = ConfigureShadowTile(tileIndex, split, tileSize);
            shadowData[i].z = tileOffset.x * tileScale;
            shadowData[i].w = tileOffset.y * tileScale;

            shadowBuffer.SetViewProjectionMatrices(viewMatrix, projectionMatrix);
            shadowBuffer.SetGlobalFloat(shadowBiasID, cull.visibleLights[i].light.shadowBias);
            context.ExecuteCommandBuffer(shadowBuffer);
            shadowBuffer.Clear();

            var shadowSettings = new DrawShadowsSettings(cull, i);
            //用球剔除 xyz是中心点  w是半径
            shadowSettings.splitData.cullingSphere = splitData.cullingSphere;
            context.DrawShadows(ref shadowSettings);


            CalculateWorldToShadowMatrix(
                ref viewMatrix, ref projectionMatrix, out worldToShadowMatrices[i]);


            if (shadowData[i].y <= 0f)
            {
                hardShadows = true;
            }
            else
            {
                softShadows = true;
            }

            tileIndex += 1;
        }

        //渲染完成禁用裁剪   不然平常渲染也会收到影响
        shadowBuffer.DisableScissorRect();

        shadowBuffer.SetGlobalTexture(shadowMapID, shadowMap);
        shadowBuffer.SetGlobalMatrixArray(worldToShadowMatricesID, worldToShadowMatrices);
        shadowBuffer.SetGlobalVectorArray(shadowDataID, shadowData);
        float invShadowMapSize = 1f / shadowMapSize;

        shadowBuffer.SetGlobalVector(shadowMapSizeID
                                     , new Vector4(invShadowMapSize, invShadowMapSize, shadowMapSize, shadowMapSize));
        //if (haveSoftShadow == LightShadows.Soft)
        //{
        //    shadowBuffer.EnableShaderKeyword(shadowSoftKeyword);
        //}
        //else
        //{
        //    shadowBuffer.DisableShaderKeyword(shadowSoftKeyword);
        //}
        //下面是上面的封装
        CoreUtils.SetKeyword(shadowBuffer, shadowsHardKeyword, hardShadows);
        CoreUtils.SetKeyword(shadowBuffer, shadowsSoftKeyword, softShadows);

        shadowBuffer.EndSample("Render Addition Shadows");
        context.ExecuteCommandBuffer(shadowBuffer);
        shadowBuffer.Clear();
    }
示例#13
0
    // 绘制ShadowMap
    void RenderShadows(ScriptableRenderContext context)
    {
        // 计算阴影图集的划分尺度
        int split;

        if (shadowTileCount <= 1)
        {
            split = 1;
        }
        else if (shadowTileCount <= 4)
        {
            split = 2;
        }
        else if (shadowTileCount <= 9)
        {
            split = 3;
        }
        else
        {
            split = 4;
        }

        // 子图集的大小
        float tileSize  = shadowMapSize / split;
        float tileScale = 1f / split;

        shadowMap = SetShadowRenderTarget();

        shadowBuffer.BeginSample("HY Render Shadows");

        // 设置全局变量
        shadowBuffer.SetGlobalVector(globalShadowDataId, new Vector4(tileScale, shadowDistance * shadowDistance));

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

        int tileIndex = 0;

        bool hardShadows = false;
        bool softShadows = false;

        // 如果存在主光,需要跳过
        for (int i = mainLightExists ? 1 : 0; i < cull.visibleLights.Count; i++)
        {
            if (i == maxVisibleLights)
            {
                break;
            }

            // 强度不为正,直接跳过
            if (shadowData[i].x <= 0f)
            {
                continue;
            }

            // 获取灯的视矩阵和投影矩阵
            Matrix4x4       viewMatrix, projectionMatrix;
            ShadowSplitData splitData;
            bool            validShadows;
            if (shadowData[i].z > 0f)
            {
                validShadows = cull.ComputeDirectionalShadowMatricesAndCullingPrimitives(
                    i, 0, 1, Vector3.right, (int)tileSize,
                    cull.visibleLights[i].light.shadowNearPlane,
                    out viewMatrix, out projectionMatrix, out splitData);
            }
            else
            {
                validShadows = cull.ComputeSpotShadowMatricesAndCullingPrimitives(i, out viewMatrix, out projectionMatrix, out splitData);
            }
            if (!validShadows)
            {
                // 获取矩阵失败则强度置0
                shadowData[i].x = 0f;
                continue;
            }

            Vector2 tileOffset = ConfigureShadowTile(tileIndex, split, tileSize);
            // 存储地图集的偏移
            shadowData[i].z = tileOffset.x * tileScale;
            shadowData[i].w = tileOffset.y * tileScale;

            // 设置灯的视矩阵和投影矩阵
            shadowBuffer.SetViewProjectionMatrices(viewMatrix, projectionMatrix);
            // 设置阴影偏移
            shadowBuffer.SetGlobalFloat(shadowBiasId, cull.visibleLights[i].light.shadowBias);
            context.ExecuteCommandBuffer(shadowBuffer);
            shadowBuffer.Clear();

            // 绘制阴影
            var shadowSettings = new DrawShadowsSettings(cull, i);
            // 设置方向光的剔除球,其他光不受影响
            shadowSettings.splitData.cullingSphere = splitData.cullingSphere;
            context.DrawShadows(ref shadowSettings);

            CalculateWorldToShadowMatrix(ref viewMatrix, ref projectionMatrix, out worldToShadowMatrices[i]);

            tileIndex += 1;

            if (shadowData[i].y <= 0f)
            {
                hardShadows = true;
            }
            else
            {
                softShadows = true;
            }
        }

        // 关闭裁剪
        shadowBuffer.DisableScissorRect();

        // 设置ShadowMap
        shadowBuffer.SetGlobalTexture(shadowMapId, shadowMap);

        // 设置世界空间到阴影空间的转换矩阵
        shadowBuffer.SetGlobalMatrixArray(worldToShadowMatricesId, worldToShadowMatrices);

        // 设置阴影数据
        shadowBuffer.SetGlobalVectorArray(shadowDataId, shadowData);

        // 设置阴影纹理大小
        float invShadowMapSize = 1f / shadowMapSize;

        shadowBuffer.SetGlobalVector(shadowMapSizeId, new Vector4(invShadowMapSize, invShadowMapSize, shadowMapSize, shadowMapSize));

        // 设置阴影关键字
        CoreUtils.SetKeyword(shadowBuffer, shadowsHardKeyword, hardShadows);
        CoreUtils.SetKeyword(shadowBuffer, shadowsSoftKeyword, softShadows);

        shadowBuffer.EndSample("HY Render Shadows");
        context.ExecuteCommandBuffer(shadowBuffer);
        shadowBuffer.Clear();
    }
示例#14
0
    public static void Render(ScriptableRenderContext context, IEnumerable <Camera> cameras, SRP07CustomParameter SRP07CP)
    {
        string tx = "";

        foreach (Camera camera in cameras)
        {
            ScriptableCullingParameters cullingParams;

            // Stereo-aware culling parameters are configured to perform a single cull for both eyes
            if (!CullResults.GetCullingParameters(camera, out cullingParams))
            {
                continue;
            }
            CullResults cull = new CullResults();
            CullResults.Cull(ref cullingParams, context, ref cull);

            // Setup camera for rendering (sets render target, view/projection matrices and other
            // per-camera built-in shader variables).
            context.SetupCameraProperties(camera);

            // clear depth buffer
            CommandBuffer cmd = new CommandBuffer();
            cmd.ClearRenderTarget(true, !SRP07CP.DrawSkybox, SRP07CP.ClearColor);
            context.ExecuteCommandBuffer(cmd);
            cmd.Release();

            // Setup global lighting shader variables
            SetupLightShaderVariables(cull.visibleLights, context);

            if (SRP07CP.DrawSkybox)
            {
                // Draw skybox
                context.DrawSkybox(camera);
            }

            // Setup DrawSettings and FilterSettings
            ShaderPassName          passName       = new ShaderPassName("BasicPass");
            DrawRendererSettings    drawSettings   = new DrawRendererSettings(camera, passName);
            FilterRenderersSettings filterSettings = new FilterRenderersSettings(true);

            // ////////////////////////////////////////////////////////////
            VisibleLight[]        ls = cull.visibleLights.ToArray();
            DrawShadowsSettings[] shadowsSettings = new DrawShadowsSettings[ls.Length];

            for (int i = 0; i < shadowsSettings.Length; i++)
            {
                shadowsSettings[i] = new DrawShadowsSettings(cull, i);
            }

            /*
             * if(camera == Camera.main) //Only generate result from main cam
             * {
             *  tx += "DrawShadowsSettings" + "\n"+ "\n";
             *
             *  for (int i=0; i<ls.Length; i++)
             *  {
             *      tx += "lightIndex = " + shadowsSettings[i].lightIndex + " (" + ls[i].light.name + ") " + "\n";
             *      tx += "splitData.cullingPlaneCount = " + shadowsSettings[i].splitData.cullingPlaneCount + "\n";
             *      tx += "splitData.cullingSphere = " + shadowsSettings[i].splitData.cullingSphere + "\n"+ "\n";
             *  }
             *
             *  // Output to text
             *  if (textMesh != null)
             *  {
             *      textMesh.text = tx;
             *      Debug.Log("<color=#0F0>TextMesh is updated</color>");
             *  }
             *  else
             *  {
             *      tx = "<color=#F00>TextMesh is null</color> Please hit play if you hasn't";
             *      Debug.Log(tx);
             *  }
             * }
             */
            // ////////////////////////////////////////////////////////////

            if (SRP07CP.DrawOpaque)
            {
                // Draw opaque objects using BasicPass shader pass
                drawSettings.sorting.flags      = SortFlags.CommonOpaque;
                filterSettings.renderQueueRange = RenderQueueRange.opaque;
                context.DrawRenderers(cull.visibleRenderers, ref drawSettings, filterSettings);

                for (int i = 0; i < shadowsSettings.Length; i++)
                {
                    //if(ls[i].light.shadows != LightShadows.None)
                    //context.DrawShadows(ref shadowsSettings[i]);
                }
            }

            if (SRP07CP.DrawTransparent)
            {
                // Draw transparent objects using BasicPass shader pass
                drawSettings.sorting.flags      = SortFlags.CommonTransparent;
                filterSettings.renderQueueRange = RenderQueueRange.transparent;
                context.DrawRenderers(cull.visibleRenderers, ref drawSettings, filterSettings);
            }

            context.Submit();
        }
    }
        void RenderMainLightCascadeShadowmap(ref ScriptableRenderContext context, ref CullResults cullResults, ref LightData lightData, ref ShadowData shadowData)
        {
            int shadowLightIndex = lightData.mainLightIndex;

            if (shadowLightIndex == -1)
            {
                return;
            }

            VisibleLight shadowLight = lightData.visibleLights[shadowLightIndex];
            Light        light       = shadowLight.light;

            Debug.Assert(shadowLight.lightType == LightType.Directional);

            if (light.shadows == LightShadows.None)
            {
                return;
            }

            Bounds bounds;

            if (!cullResults.GetShadowCasterBounds(shadowLightIndex, out bounds))
            {
                return;
            }

            CommandBuffer cmd = CommandBufferPool.Get(k_RenderMainLightShadowmapTag);

            using (new ProfilingSample(cmd, k_RenderMainLightShadowmapTag))
            {
                m_ShadowCasterCascadesCount = shadowData.mainLightShadowCascadesCount;

                int   shadowResolution = ShadowUtils.GetMaxTileResolutionInAtlas(shadowData.mainLightShadowmapWidth, shadowData.mainLightShadowmapHeight, m_ShadowCasterCascadesCount);
                float shadowNearPlane  = light.shadowNearPlane;

                Matrix4x4 view, proj;
                var       settings = new DrawShadowsSettings(cullResults, shadowLightIndex);

                m_MainLightShadowmapTexture = RenderTexture.GetTemporary(shadowData.mainLightShadowmapWidth,
                                                                         shadowData.mainLightShadowmapHeight, k_ShadowmapBufferBits, m_ShadowmapFormat);
                m_MainLightShadowmapTexture.filterMode = FilterMode.Bilinear;
                m_MainLightShadowmapTexture.wrapMode   = TextureWrapMode.Clamp;
                SetRenderTarget(cmd, m_MainLightShadowmapTexture, RenderBufferLoadAction.DontCare,
                                RenderBufferStoreAction.Store, ClearFlag.Depth, Color.black, TextureDimension.Tex2D);

                bool success = false;
                for (int cascadeIndex = 0; cascadeIndex < m_ShadowCasterCascadesCount; ++cascadeIndex)
                {
                    success = ShadowUtils.ExtractDirectionalLightMatrix(ref cullResults, ref shadowData, shadowLightIndex, cascadeIndex, shadowResolution, shadowNearPlane, out m_CascadeSplitDistances[cascadeIndex], out m_CascadeSlices[cascadeIndex], out view, out proj);
                    if (success)
                    {
                        settings.splitData.cullingSphere = m_CascadeSplitDistances[cascadeIndex];
                        Vector4 shadowBias = ShadowUtils.GetShadowBias(ref shadowLight, shadowLightIndex, ref shadowData, proj, shadowResolution);
                        ShadowUtils.SetupShadowCasterConstantBuffer(cmd, ref shadowLight, shadowBias);
                        ShadowUtils.RenderShadowSlice(cmd, ref context, ref m_CascadeSlices[cascadeIndex], ref settings, proj, view);
                    }
                }

                if (success)
                {
                    SetupMainLightShadowReceiverConstants(cmd, ref shadowData, shadowLight);
                }
            }
            context.ExecuteCommandBuffer(cmd);
            CommandBufferPool.Release(cmd);
        }
        void RenderLocalShadowmapAtlas(ref ScriptableRenderContext context, ref CullResults cullResults, ref LightData lightData, ref ShadowData shadowData)
        {
            List <int>          localLightIndices = lightData.visibleLocalLightIndices;
            List <VisibleLight> visibleLights     = lightData.visibleLights;

            int shadowCastingLightsCount = 0;
            int localLightsCount         = localLightIndices.Count;

            for (int i = 0; i < localLightsCount; ++i)
            {
                VisibleLight shadowLight = visibleLights[localLightIndices[i]];

                if (shadowLight.lightType == LightType.Spot && shadowLight.light.shadows != LightShadows.None)
                {
                    shadowCastingLightsCount++;
                }
            }

            if (shadowCastingLightsCount == 0)
            {
                return;
            }

            Matrix4x4 view, proj;
            Bounds    bounds;

            CommandBuffer cmd = CommandBufferPool.Get(k_RenderLocalShadows);

            using (new ProfilingSample(cmd, k_RenderLocalShadows))
            {
                // TODO: Add support to point light shadows. We make a simplification here that only works
                // for spot lights and with max spot shadows per pass.
                int atlasWidth      = shadowData.localShadowAtlasWidth;
                int atlasHeight     = shadowData.localShadowAtlasHeight;
                int sliceResolution = LightweightShadowUtils.GetMaxTileResolutionInAtlas(atlasWidth, atlasHeight, shadowCastingLightsCount);

                m_LocalShadowmapTexture = RenderTexture.GetTemporary(shadowData.localShadowAtlasWidth,
                                                                     shadowData.localShadowAtlasHeight, k_ShadowmapBufferBits, m_LocalShadowmapFormat);
                m_LocalShadowmapTexture.filterMode = FilterMode.Bilinear;
                m_LocalShadowmapTexture.wrapMode   = TextureWrapMode.Clamp;

                SetRenderTarget(cmd, m_LocalShadowmapTexture, RenderBufferLoadAction.DontCare, RenderBufferStoreAction.Store,
                                ClearFlag.Depth, Color.black, TextureDimension.Tex2D);

                for (int i = 0; i < localLightsCount; ++i)
                {
                    int          shadowLightIndex = localLightIndices[i];
                    VisibleLight shadowLight      = visibleLights[shadowLightIndex];
                    Light        light            = shadowLight.light;

                    // TODO: Add support to point light shadows
                    if (shadowLight.lightType != LightType.Spot || shadowLight.light.shadows == LightShadows.None)
                    {
                        continue;
                    }

                    if (!cullResults.GetShadowCasterBounds(shadowLightIndex, out bounds))
                    {
                        continue;
                    }

                    Matrix4x4 shadowTransform;
                    bool      success = LightweightShadowUtils.ExtractSpotLightMatrix(ref cullResults, ref shadowData,
                                                                                      shadowLightIndex, out shadowTransform, out view, out proj);

                    if (success)
                    {
                        // This way of computing the shadow slice only work for spots and with most 4 shadow casting lights per pass
                        // Change this when point lights are supported.
                        Debug.Assert(shadowCastingLightsCount <= 4 && shadowLight.lightType == LightType.Spot);

                        // TODO: We need to pass bias and scale list to shader to be able to support multiple
                        // shadow casting local lights.
                        m_LocalLightSlices[i].offsetX         = (i % 2) * sliceResolution;
                        m_LocalLightSlices[i].offsetY         = (i / 2) * sliceResolution;
                        m_LocalLightSlices[i].resolution      = sliceResolution;
                        m_LocalLightSlices[i].shadowTransform = shadowTransform;

                        m_LocalShadowStrength[i] = light.shadowStrength;

                        if (shadowCastingLightsCount > 1)
                        {
                            LightweightShadowUtils.ApplySliceTransform(ref m_LocalLightSlices[i], atlasWidth, atlasHeight);
                        }

                        var settings = new DrawShadowsSettings(cullResults, shadowLightIndex);
                        LightweightShadowUtils.SetupShadowCasterConstants(cmd, ref shadowLight, proj, sliceResolution);
                        LightweightShadowUtils.RenderShadowSlice(cmd, ref context, ref m_LocalLightSlices[i], ref settings, proj, view);
                    }
                }

                SetupLocalLightsShadowReceiverConstants(cmd, ref shadowData);
            }
            context.ExecuteCommandBuffer(cmd);
            CommandBufferPool.Release(cmd);
        }
示例#17
0
    private void RenderShadows(ScriptableRenderContext renderContext)
    {
        shadowMap            = RenderTexture.GetTemporary(shadowMapSize, shadowMapSize, 16, RenderTextureFormat.Shadowmap);
        shadowMap.filterMode = FilterMode.Bilinear;
        shadowMap.wrapMode   = TextureWrapMode.Clamp;
        //tell the GPU to render to our shaow map,load and store more precise texture
        CoreUtils.SetRenderTarget(shadowBuffer, shadowMap, RenderBufferLoadAction.DontCare, RenderBufferStoreAction.Store, ClearFlag.Depth);

        shadowBuffer.BeginSample("Render Shadows");
        renderContext.ExecuteCommandBuffer(shadowBuffer);
        shadowBuffer.Clear();

        Matrix4x4       viewMatrix, projectionMatrix;
        ShadowSplitData splitData;

        cull.ComputeSpotShadowMatricesAndCullingPrimitives(0, out viewMatrix, out projectionMatrix, out splitData);
        shadowBuffer.SetViewProjectionMatrices(viewMatrix, projectionMatrix);
        shadowBuffer.SetGlobalFloat(shadowBiasId, cull.visibleLights[0].light.shadowBias);
        renderContext.ExecuteCommandBuffer(shadowBuffer);
        shadowBuffer.Clear();

        var shadowSettings = new DrawShadowsSettings(cull, 0);

        renderContext.DrawShadows(ref shadowSettings);

        //Opengl Z is reversed
        if (SystemInfo.usesReversedZBuffer)
        {
            projectionMatrix.m20 = -projectionMatrix.m20;
            projectionMatrix.m21 = -projectionMatrix.m21;
            projectionMatrix.m22 = -projectionMatrix.m22;
            projectionMatrix.m23 = -projectionMatrix.m23;
        }
        //clip space goes from -1 to 1,while texture coordinates and depth go from 0 to 1.so need to tranfer the matrix
        var scaleOffset = Matrix4x4.identity;

        scaleOffset.m00 = scaleOffset.m11 = scaleOffset.m22 = 0.5f;
        scaleOffset.m03 = scaleOffset.m13 = scaleOffset.m23 = 0.5f;

        Matrix4x4 worldToShadowMatrix = scaleOffset * (projectionMatrix * viewMatrix);

        shadowBuffer.SetGlobalMatrix(worldToShadowMatrixId, worldToShadowMatrix);
        shadowBuffer.SetGlobalTexture(shadowMapId, shadowMap);
        shadowBuffer.SetGlobalFloat(shadowStrengthId, cull.visibleLights[0].light.shadowStrength);

        float invShadowMapSize = 1f / shadowMapSize;

        shadowBuffer.SetGlobalVector(shadowMapSizeId, new Vector4(invShadowMapSize, invShadowMapSize, shadowMapSize, shadowMapSize));

        // if(cull.visibleLights[0].light.shadows == LightShadows.Soft){
        //     shadowBuffer.EnableShaderKeyword(shadowSoftKeyword);
        // }else
        // {
        //     shadowBuffer.DisableShaderKeyword(shadowSoftKeyword);
        // }

        CoreUtils.SetKeyword(shadowBuffer, shadowSoftKeyword, cull.visibleLights[0].light.shadows == LightShadows.Soft);

        shadowBuffer.EndSample("Render Shadows");
        renderContext.ExecuteCommandBuffer(shadowBuffer);
        shadowBuffer.Clear();
    }
        private void RenderLocalShadowmapAtlas(ref CullResults cullResults, ref LightData lightData, ref ScriptableRenderContext context)
        {
            List <int>          localLightIndices = lightData.localLightIndices;
            List <VisibleLight> visibleLights     = lightData.visibleLights;

            int shadowCastingLightsCount = 0;
            int localLightsCount         = localLightIndices.Count;

            for (int i = 0; i < localLightsCount; ++i)
            {
                VisibleLight shadowLight = visibleLights[localLightIndices[i]];

                if (shadowLight.lightType == LightType.Spot && shadowLight.light.shadows != LightShadows.None)
                {
                    shadowCastingLightsCount++;
                }
            }

            if (shadowCastingLightsCount == 0)
            {
                return;
            }

            CommandBuffer cmd = CommandBufferPool.Get("Prepare Local Lights Shadowmap");
            Matrix4x4     view, proj;
            Bounds        bounds;

            // TODO: Add support to point light shadows. We make a simplification here that only works
            // for spot lights and with max spot shadows per pass.
            int atlasWidth      = m_ShadowSettings.localShadowAtlasWidth;
            int atlasHeight     = m_ShadowSettings.localShadowAtlasHeight;
            int sliceResolution = GetMaxTileResolutionInAtlas(atlasWidth, atlasHeight, shadowCastingLightsCount);
            int shadowSampling  = 0;

            m_LocalShadowmapTexture            = RenderTexture.GetTemporary(m_LocalShadowmapDescriptor);
            m_LocalShadowmapTexture.filterMode = FilterMode.Bilinear;
            m_LocalShadowmapTexture.wrapMode   = TextureWrapMode.Clamp;

            CoreUtils.SetRenderTarget(cmd, m_LocalShadowmapTexture, ClearFlag.Depth);

            for (int i = 0; i < localLightsCount; ++i)
            {
                int          shadowLightIndex = localLightIndices[i];
                VisibleLight shadowLight      = visibleLights[shadowLightIndex];
                Light        light            = shadowLight.light;

                // TODO: Add support to point light shadows
                if (shadowLight.lightType != LightType.Spot || shadowLight.light.shadows == LightShadows.None)
                {
                    continue;
                }

                if (!cullResults.GetShadowCasterBounds(shadowLightIndex, out bounds))
                {
                    continue;
                }

                var settings = new DrawShadowsSettings(cullResults, shadowLightIndex);

                if (cullResults.ComputeSpotShadowMatricesAndCullingPrimitives(shadowLightIndex, out view, out proj, out settings.splitData))
                {
                    // This way of computing the shadow slice only work for spots and with most 4 shadow casting lights per pass
                    // Change this when point lights are supported.
                    Debug.Assert(localLightsCount <= 4 && shadowLight.lightType == LightType.Spot);

                    // TODO: We need to pass bias and scale list to shader to be able to support multiple
                    // shadow casting local lights.
                    m_LocalLightSlices[i].offsetX         = (i % 2) * sliceResolution;
                    m_LocalLightSlices[i].offsetY         = (i / 2) * sliceResolution;
                    m_LocalLightSlices[i].resolution      = sliceResolution;
                    m_LocalLightSlices[i].shadowTransform = GetShadowTransform(proj, view);

                    if (shadowCastingLightsCount > 1)
                    {
                        ApplySliceTransform(ref m_LocalLightSlices[i], atlasWidth, atlasHeight);
                    }

                    SetupShadowCasterConstants(cmd, ref shadowLight, proj, sliceResolution);
                    RenderShadowSlice(cmd, ref context, ref m_LocalLightSlices[i], proj, view, settings);
                    m_LocalShadowStrength[i] = light.shadowStrength;
                    shadowSampling           = Math.Max(shadowSampling, (int)light.shadows);
                }
            }

            SetupLocalLightsShadowReceiverConstants(cmd, ref context);

            m_LocalShadowmapQuality = (LightShadows)Math.Min(shadowSampling, (int)m_ShadowSettings.directionalShadowQuality);
            context.ExecuteCommandBuffer(cmd);
            CommandBufferPool.Release(cmd);
        }
示例#19
0
        private bool RenderShadows(ref CullResults cullResults, ref VisibleLight shadowLight, int shadowLightIndex, ref ScriptableRenderContext context)
        {
            m_ShadowCasterCascadesCount = m_ShadowSettings.directionalLightCascadeCount;

            if (shadowLight.lightType == LightType.Spot)
            {
                m_ShadowCasterCascadesCount = 1;
            }

            int shadowResolution = GetMaxTileResolutionInAtlas(m_ShadowSettings.shadowAtlasWidth, m_ShadowSettings.shadowAtlasHeight, m_ShadowCasterCascadesCount);

            Bounds bounds;

            if (!cullResults.GetShadowCasterBounds(shadowLightIndex, out bounds))
            {
                return(false);
            }

            var setRenderTargetCommandBuffer = CommandBufferPool.Get();

            setRenderTargetCommandBuffer.name = "Render packed shadows";
            setRenderTargetCommandBuffer.GetTemporaryRT(m_ShadowMapProperty, m_ShadowSettings.shadowAtlasWidth,
                                                        m_ShadowSettings.shadowAtlasHeight, kShadowDepthBufferBits, FilterMode.Bilinear, RenderTextureFormat.Depth);
            setRenderTargetCommandBuffer.SetRenderTarget(m_ShadowMapRTID);
            setRenderTargetCommandBuffer.ClearRenderTarget(true, true, Color.black);
            context.ExecuteCommandBuffer(setRenderTargetCommandBuffer);
            CommandBufferPool.Release(setRenderTargetCommandBuffer);

            float   shadowNearPlane = m_Asset.ShadowNearOffset;
            Vector3 splitRatio      = m_ShadowSettings.directionalLightCascades;

            Matrix4x4 view, proj;
            var       settings      = new DrawShadowsSettings(cullResults, shadowLightIndex);
            bool      needRendering = false;

            if (shadowLight.lightType == LightType.Spot)
            {
                needRendering = cullResults.ComputeSpotShadowMatricesAndCullingPrimitives(shadowLightIndex, out view, out proj,
                                                                                          out settings.splitData);

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

                SetupShadowSliceTransform(0, shadowResolution, proj, view);
                RenderShadowSlice(ref context, 0, proj, view, settings);
            }
            else if (shadowLight.lightType == LightType.Directional)
            {
                for (int cascadeIdx = 0; cascadeIdx < m_ShadowCasterCascadesCount; ++cascadeIdx)
                {
                    needRendering = cullResults.ComputeDirectionalShadowMatricesAndCullingPrimitives(shadowLightIndex,
                                                                                                     cascadeIdx, m_ShadowCasterCascadesCount, splitRatio, shadowResolution, shadowNearPlane, out view, out proj,
                                                                                                     out settings.splitData);

                    m_DirectionalShadowSplitDistances[cascadeIdx]    = settings.splitData.cullingSphere;
                    m_DirectionalShadowSplitDistances[cascadeIdx].w *= settings.splitData.cullingSphere.w;

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

                    SetupShadowSliceTransform(cascadeIdx, shadowResolution, proj, view);
                    RenderShadowSlice(ref context, cascadeIdx, proj, view, settings);
                }
            }
            else
            {
                Debug.LogWarning("Only spot and directional shadow casters are supported in lightweight pipeline");
                return(false);
            }

            return(true);
        }
示例#20
0
    void RenderShadows(ScriptableRenderContext context)
    {
        int split;

        if (shadowTileCount <= 1)
        {
            split = 1;
        }
        else if (shadowTileCount <= 4)
        {
            split = 2;
        }
        else if (shadowTileCount <= 9)
        {
            split = 3;
        }
        else
        {
            split = 4;
        }

        float tileSize  = shadowMapSize / split;
        float tileScale = 1f / split;

        Rect tileViewport = new Rect(0f, 0f, tileSize, tileSize);

        shadowMap = RenderTexture.GetTemporary(shadowMapSize, 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 Shadows");
        shadowBuffer.SetGlobalVector(globalShadowDataId, new Vector4(tileScale, shadowDistance * shadowDistance));
        context.ExecuteCommandBuffer(shadowBuffer);
        shadowBuffer.Clear();

        int  tileIndex   = 0;
        bool hardShadows = false;
        bool softShadows = false;

        for (int i = 0; i < cull.visibleLights.Count; ++i)
        {
            if (i == maxVisibleLights)
            {
                break;
            }

            if (shadowData[i].x <= 0f)
            {
                continue;
            }

            Matrix4x4       viewMatrix, projectionMatrix;
            ShadowSplitData splitData;
            bool            validShadow;
            if (shadowData[i].z > 0f)
            {
                validShadow = cull.ComputeDirectionalShadowMatricesAndCullingPrimitives(
                    i, 0, 1, Vector3.right, (int)tileSize,
                    cull.visibleLights[i].light.shadowNearPlane,
                    out viewMatrix, out projectionMatrix, out splitData);
            }
            else
            {
                validShadow = cull.ComputeSpotShadowMatricesAndCullingPrimitives(i, out viewMatrix, out projectionMatrix, out splitData);
            }
            if (!validShadow)
            {
                shadowData[i].x = 0f;
                continue;
            }
            float tileOffsetX = i % split;
            float tileOffsetY = i / split;
            tileViewport.x  = tileOffsetX * tileSize;
            tileViewport.y  = tileOffsetY * tileSize;
            shadowData[i].z = tileOffsetX * tileScale;
            shadowData[i].w = tileOffsetY * tileScale;

            shadowBuffer.SetViewport(tileViewport);
            shadowBuffer.EnableScissorRect(new Rect(
                                               tileViewport.x + 4f, tileViewport.y + 4f,
                                               tileSize - 8f, tileSize - 8f
                                               ));

            shadowBuffer.SetViewProjectionMatrices(viewMatrix, projectionMatrix);
            shadowBuffer.SetGlobalFloat(
                shadowBiasId, cull.visibleLights[i].light.shadowBias
                );
            shadowBuffer.SetGlobalVectorArray(shadowDataId, shadowData);
            context.ExecuteCommandBuffer(shadowBuffer);
            shadowBuffer.Clear();

            var shadowSettings = new DrawShadowsSettings(cull, i);
            shadowSettings.splitData.cullingSphere = splitData.cullingSphere;
            context.DrawShadows(ref shadowSettings);

            if (SystemInfo.usesReversedZBuffer)
            {
                projectionMatrix.m20 = -projectionMatrix.m20;
                projectionMatrix.m21 = -projectionMatrix.m21;
                projectionMatrix.m22 = -projectionMatrix.m22;
                projectionMatrix.m23 = -projectionMatrix.m23;
            }
            var scaleOffset = Matrix4x4.TRS(Vector3.one * 0.5f, Quaternion.identity, Vector3.one * 0.5f);
            worldToShadowMatrices[i] = scaleOffset * (projectionMatrix * viewMatrix);

            //if (split > 1)
            //{
            //    var tileMatrix = Matrix4x4.identity;
            //    tileMatrix.m00 = tileMatrix.m11 = tileScale;
            //    tileMatrix.m03 = tileOffsetX * tileScale;
            //    tileMatrix.m13 = tileOffsetY * tileScale;

            //    worldToShadowMatrices[i] = tileMatrix * worldToShadowMatrices[i];
            //}
            shadowBuffer.SetGlobalMatrixArray(worldToShadowMatricesId, worldToShadowMatrices);

            tileIndex += 1;

            if (shadowData[i].y <= 0f)
            {
                hardShadows = true;
            }
            else
            {
                softShadows = true;
            }
        }

        shadowBuffer.DisableScissorRect();
        shadowBuffer.SetGlobalTexture(shadowMapId, shadowMap);

        float invShadowMapSize = 1f / shadowMapSize;

        shadowBuffer.SetGlobalVector(
            shadowMapSizeId, new Vector4(
                invShadowMapSize, invShadowMapSize, shadowMapSize, shadowMapSize
                )
            );

        CoreUtils.SetKeyword(shadowBuffer, shadowsSoftKeyword, softShadows);

        CoreUtils.SetKeyword(shadowBuffer, shadowsHardKeyword, hardShadows);

        shadowBuffer.EndSample("Render Shadows");
        context.ExecuteCommandBuffer(shadowBuffer);
        shadowBuffer.Clear();
    }
示例#21
0
    void RenderShadows(ScriptableRenderContext context)
    {
        int split;

        if (shadowTileCount <= 1)
        {
            split = 1;
        }
        else if (shadowTileCount <= 4)
        {
            split = 2;
        }
        else if (shadowTileCount <= 9)
        {
            split = 3;
        }
        else
        {
            split = 4;
        }
        float tileSize  = shadowMapSize / split;
        float tileScale = 1f / split;

        shadowMap = SetShadowRenderTarget();
        shadowBuffer.BeginSample("Render Shadows");
        shadowBuffer.SetGlobalVector(globalShadowDataId, new Vector4(tileScale, shadowDistance * shadowDistance));
        context.ExecuteCommandBuffer(shadowBuffer);
        shadowBuffer.Clear();

        bool softShadows = false;
        bool hardShadows = false;
        int  tileIndex   = 0;

        for (int i = mainLightExists ? 1 : 0; i < cull.visibleLights.Count; i++)
        {
            if (i == MAX_VISIBLE_LIGHTS)
            {
                break;
            }

            if (shadowData[i].x <= 0f)
            {
                continue;
            }

            Matrix4x4       viewMatrix, projectionMatrix;
            ShadowSplitData splitData;

            bool validShadows = false;
            if (shadowData[i].z > 0f)
            {
                validShadows = cull.ComputeDirectionalShadowMatricesAndCullingPrimitives(i, 0, 1, Vector3.right, (int)tileSize, cull.visibleLights[i].light.shadowNearPlane, out viewMatrix, out projectionMatrix, out splitData);
            }
            else
            {
                validShadows = cull.ComputeSpotShadowMatricesAndCullingPrimitives(i, out viewMatrix, out projectionMatrix, out splitData);
            }
            if (!validShadows)
            {
                shadowData[i].x = 0f;
                continue;
            }

            Vector2 tileOffset = ConfigureShadowTile(tileIndex, split, tileSize);
            shadowData[i].z = tileOffset.x * tileScale;
            shadowData[i].w = tileOffset.x * tileScale;

            shadowBuffer.SetViewProjectionMatrices(viewMatrix, projectionMatrix);

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

            var shadowSettings = new DrawShadowsSettings(cull, i);
            shadowSettings.splitData.cullingSphere = splitData.cullingSphere;
            context.DrawShadows(ref shadowSettings);

            CalculateWorldToShadowMatrix(ref viewMatrix, ref projectionMatrix, out worldToShadowMatrices[i]);

            if (shadowData[i].y <= 0f)
            {
                hardShadows = true;
            }
            else
            {
                softShadows = true;
            }

            shadowBuffer.SetGlobalFloat(shadowBiasId, cull.visibleLights[i].light.shadowBias);

            tileIndex += 1;
        }

        CoreUtils.SetKeyword(shadowBuffer, shadowsHardKeyword, hardShadows);
        CoreUtils.SetKeyword(shadowBuffer, shadowsSoftKeyword, softShadows);

        shadowBuffer.SetGlobalMatrixArray(worldToShadowMatricesId, worldToShadowMatrices);

        shadowBuffer.SetGlobalVectorArray(shadowDataId, shadowData);

        float invShadowMapSize = 1f / shadowMapSize;

        shadowBuffer.SetGlobalVector(shadowMapSizeId, new Vector4(invShadowMapSize, invShadowMapSize, shadowMapSize, shadowMapSize));

        shadowBuffer.DisableScissorRect();

        shadowBuffer.SetGlobalTexture(shadowMapId, shadowMap);

        shadowBuffer.EndSample("Render Shadows");
        context.ExecuteCommandBuffer(shadowBuffer);
        shadowBuffer.Clear();
    }
示例#22
0
        void RenderDirectionalCascadeShadowmap(ref ScriptableRenderContext context, ref CullResults cullResults, ref LightData lightData, ref ShadowData shadowData)
        {
            LightShadows shadowQuality    = LightShadows.None;
            int          shadowLightIndex = lightData.mainLightIndex;

            if (shadowLightIndex == -1)
            {
                return;
            }

            VisibleLight shadowLight = lightData.visibleLights[shadowLightIndex];
            Light        light       = shadowLight.light;

            Debug.Assert(shadowLight.lightType == LightType.Directional);

            if (light.shadows == LightShadows.None)
            {
                return;
            }

            Bounds bounds;

            if (!cullResults.GetShadowCasterBounds(shadowLightIndex, out bounds))
            {
                return;
            }

            CommandBuffer cmd = CommandBufferPool.Get(k_RenderDirectionalShadowmapTag);

            using (new ProfilingSample(cmd, k_RenderDirectionalShadowmapTag))
            {
                m_ShadowCasterCascadesCount = shadowData.directionalLightCascadeCount;

                int   shadowResolution = LightweightShadowUtils.GetMaxTileResolutionInAtlas(shadowData.directionalShadowAtlasWidth, shadowData.directionalShadowAtlasHeight, m_ShadowCasterCascadesCount);
                float shadowNearPlane  = light.shadowNearPlane;

                Matrix4x4 view, proj;
                var       settings = new DrawShadowsSettings(cullResults, shadowLightIndex);

                m_DirectionalShadowmapTexture = RenderTexture.GetTemporary(shadowData.directionalShadowAtlasWidth,
                                                                           shadowData.directionalShadowAtlasHeight, k_ShadowmapBufferBits, m_ShadowmapFormat);
                m_DirectionalShadowmapTexture.filterMode = FilterMode.Bilinear;
                m_DirectionalShadowmapTexture.wrapMode   = TextureWrapMode.Clamp;
                SetRenderTarget(cmd, m_DirectionalShadowmapTexture, RenderBufferLoadAction.DontCare,
                                RenderBufferStoreAction.Store, ClearFlag.Depth, Color.black, TextureDimension.Tex2D);

                bool success = false;
                for (int cascadeIndex = 0; cascadeIndex < m_ShadowCasterCascadesCount; ++cascadeIndex)
                {
                    success = LightweightShadowUtils.ExtractDirectionalLightMatrix(ref cullResults, ref shadowData, shadowLightIndex, cascadeIndex, shadowResolution, shadowNearPlane, out m_CascadeSplitDistances[cascadeIndex], out m_CascadeSlices[cascadeIndex], out view, out proj);
                    if (success)
                    {
                        LightweightShadowUtils.SetupShadowCasterConstants(cmd, ref shadowLight, proj, shadowResolution);
                        LightweightShadowUtils.RenderShadowSlice(cmd, ref context, ref m_CascadeSlices[cascadeIndex], proj,
                                                                 view, settings);
                    }
                }

                if (success)
                {
                    shadowQuality = (shadowData.supportsSoftShadows) ? light.shadows : LightShadows.Hard;
                    SetupDirectionalShadowReceiverConstants(cmd, ref shadowData, shadowLight);
                }
            }
            context.ExecuteCommandBuffer(cmd);
            CommandBufferPool.Release(cmd);

            // TODO: We should have RenderingData as a readonly but currently we need this to pass shadow rendering to litpass
            shadowData.renderedDirectionalShadowQuality = shadowQuality;
        }
示例#23
0
        /// <inheritdoc/>
        public override void Execute(ScriptableRenderer renderer, ScriptableRenderContext context, ref RenderingData renderingData)
        {
            if (renderer == null)
            {
                throw new ArgumentNullException("renderer");
            }

            if (!renderingData.shadowData.supportsMainCharacterShadows)
            {
                return;
            }
            LightData lightData        = renderingData.lightData;
            int       shadowLightIndex = lightData.mainLightIndex;

            if (shadowLightIndex == -1)
            {
                return;
            }

            VisibleLight shadowLight = lightData.visibleLights[shadowLightIndex];
            ShadowData   shadowData  = renderingData.shadowData;

            if (!GetVPMatrix(shadowLight.light))
            {
                return;
            }

            CommandBuffer cmd = CommandBufferPool.Get(k_RenderMainCharacterShadowmapTag);

            using (new ProfilingSample(cmd, k_RenderMainCharacterShadowmapTag))
            {
                m_MainCharacterShadowmapTexture = RenderTexture.GetTemporary(shadowData.mainCharacterShadowmapWidth,
                                                                             shadowData.mainCharacterShadowmapHeight, k_ShadowmapBufferBits, m_ShadowmapFormat);
                m_MainCharacterShadowmapTexture.filterMode = FilterMode.Bilinear;
                m_MainCharacterShadowmapTexture.wrapMode   = TextureWrapMode.Clamp;
                m_MainCharacterShadowmapTexture.name       = "m_MainCharacterShadowmapTexture";
                SetRenderTarget(cmd, m_MainCharacterShadowmapTexture, RenderBufferLoadAction.DontCare,
                                RenderBufferStoreAction.Store, ClearFlag.Depth, Color.black, TextureDimension.Tex2D);

                Vector4 shadowBias = ShadowUtils.GetShadowBias(ref shadowLight, shadowLightIndex, ref shadowData, m_ProjMatrix, shadowData.mainCharacterShadowmapWidth);
                ShadowUtils.SetupShadowCasterConstantBuffer(cmd, ref shadowLight, shadowBias);

                cmd.SetViewProjectionMatrices(m_ViewMatrix, m_ProjMatrix);
                context.ExecuteCommandBuffer(cmd);
                cmd.Clear();

                //foreach (var r in _Renderers)
                //{
                //    for (int i = 0, imax = r.sharedMaterials.Length; i < imax; i++)
                //    {
                //        cmd.DrawRenderer(r, r.sharedMaterials[i], i, r.sharedMaterials[i].FindPass("ShadowCaster"));
                //    }
                //}
                ShadowSliceData slice = new ShadowSliceData()
                {
                    offsetX    = 0,
                    offsetY    = 0,
                    resolution = shadowData.mainCharacterShadowmapWidth
                };

                DrawShadowsSettings settings = new DrawShadowsSettings(renderingData.cullResults, shadowLightIndex);
                settings.splitData.cullingSphere = m_CullingSphere;

                ShadowUtils.RenderShadowSlice(cmd, ref context, ref slice, ref settings, m_ProjMatrix, m_ViewMatrix);

                context.ExecuteCommandBuffer(cmd);
                cmd.Clear();

                SetupMainCharacterShadowReceiverConstants(cmd, ref shadowData, shadowLight);
            }

            CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.MainCharacterShadows, true);
            CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.SoftShadows, shadowLight.light.shadows == LightShadows.Soft && shadowData.supportsSoftShadows);
            context.ExecuteCommandBuffer(cmd);
            CommandBufferPool.Release(cmd);
        }
示例#24
0
    public static void Render(ScriptableRenderContext context, IEnumerable<Camera> cameras)
    {
        foreach (Camera camera in cameras)
        {
            ScriptableCullingParameters cullingParams;

            // Stereo-aware culling parameters are configured to perform a single cull for both eyes
            if (!CullResults.GetCullingParameters(camera, out cullingParams))
                continue;
            CullResults cull = new CullResults();
            CullResults.Cull(ref cullingParams, context, ref cull);

            // Setup camera for rendering (sets render target, view/projection matrices and other
            // per-camera built-in shader variables).
            context.SetupCameraProperties(camera);

            // clear depth buffer
            CommandBuffer cmd = new CommandBuffer();
            cmd.ClearRenderTarget(true, false, Color.grey);
            context.ExecuteCommandBuffer(cmd);
            cmd.Release();

            // Setup global lighting shader variables
            //SetupLightShaderVariables(cull.visibleLights, context);

            // Draw skybox
            context.DrawSkybox(camera);

            // Setup DrawSettings and FilterSettings
            ShaderPassName passName = new ShaderPassName("BasicPass");
            DrawRendererSettings drawSettings = new DrawRendererSettings(camera, passName);
            FilterRenderersSettings filterSettings = new FilterRenderersSettings(true);

            // Draw opaque objects using BasicPass shader pass
            drawSettings.sorting.flags = SortFlags.CommonOpaque;
            filterSettings.renderQueueRange = RenderQueueRange.opaque;
            context.DrawRenderers(cull.visibleRenderers, ref drawSettings, filterSettings);

            // Draw shadow
            VisibleLight[] ls = cull.visibleLights.ToArray();
            SetupLightShaderVariables(cull.visibleLights, context);
            DrawShadowsSettings[] shadowsSettings = new DrawShadowsSettings[ls.Length];
            
            for (int i=0; i<shadowsSettings.Length; i++)
            {
                shadowsSettings[i] = new DrawShadowsSettings(cull, i);
                if(ls[i].light.shadows != LightShadows.None)
                {
                    context.DrawShadows(ref shadowsSettings[i]);
                    Debug.Log("draw shadow for light "+i);
                }
            }

            // Draw transparent objects using BasicPass shader pass
            //drawSettings.sorting.flags = SortFlags.CommonTransparent;
            //filterSettings.renderQueueRange = RenderQueueRange.transparent;
            //context.DrawRenderers(cull.visibleRenderers, ref drawSettings, filterSettings);

            context.Submit();
        }
    }
        private bool RenderDirectionalCascadeShadowmap(ref CullResults cullResults, ref LightData lightData, ref ScriptableRenderContext context)
        {
            int shadowLightIndex = lightData.mainLightIndex;

            if (shadowLightIndex == -1)
            {
                return(false);
            }

            VisibleLight shadowLight = lightData.visibleLights[shadowLightIndex];
            Light        light       = shadowLight.light;

            Debug.Assert(shadowLight.lightType == LightType.Directional);

            if (light.shadows == LightShadows.None)
            {
                return(false);
            }

            CommandBuffer cmd = CommandBufferPool.Get("Prepare Directional Shadowmap");

            m_ShadowCasterCascadesCount = m_ShadowSettings.directionalLightCascadeCount;

            int   shadowResolution = GetMaxTileResolutionInAtlas(m_ShadowSettings.directionalShadowAtlasWidth, m_ShadowSettings.directionalShadowAtlasHeight, m_ShadowCasterCascadesCount);
            float shadowNearPlane  = light.shadowNearPlane;

            Bounds bounds;

            if (!cullResults.GetShadowCasterBounds(shadowLightIndex, out bounds))
            {
                return(false);
            }

            Matrix4x4 view, proj;
            var       settings = new DrawShadowsSettings(cullResults, shadowLightIndex);

            m_DirectionalShadowmapTexture            = RenderTexture.GetTemporary(m_DirectionalShadowmapDescriptor);
            m_DirectionalShadowmapTexture.filterMode = FilterMode.Bilinear;
            m_DirectionalShadowmapTexture.wrapMode   = TextureWrapMode.Clamp;

            CoreUtils.SetRenderTarget(cmd, m_DirectionalShadowmapTexture, ClearFlag.Depth);

            bool success = false;

            for (int cascadeIndex = 0; cascadeIndex < m_ShadowCasterCascadesCount; ++cascadeIndex)
            {
                success = cullResults.ComputeDirectionalShadowMatricesAndCullingPrimitives(shadowLightIndex,
                                                                                           cascadeIndex, m_ShadowCasterCascadesCount, m_ShadowSettings.directionalLightCascades, shadowResolution, shadowNearPlane, out view, out proj,
                                                                                           out settings.splitData);

                float cullingSphereRadius = settings.splitData.cullingSphere.w;
                m_CascadeSplitDistances[cascadeIndex] = settings.splitData.cullingSphere;
                m_CascadeSplitRadii[cascadeIndex]     = cullingSphereRadius * cullingSphereRadius;

                if (!success)
                {
                    break;
                }

                m_CascadeSlices[cascadeIndex].offsetX         = (cascadeIndex % 2) * shadowResolution;
                m_CascadeSlices[cascadeIndex].offsetY         = (cascadeIndex / 2) * shadowResolution;
                m_CascadeSlices[cascadeIndex].resolution      = shadowResolution;
                m_CascadeSlices[cascadeIndex].shadowTransform = GetShadowTransform(proj, view);

                // If we have shadow cascades baked into the atlas we bake cascade transform
                // in each shadow matrix to save shader ALU and L/S
                if (m_ShadowCasterCascadesCount > 1)
                {
                    ApplySliceTransform(ref m_CascadeSlices[cascadeIndex], m_ShadowSettings.directionalShadowAtlasWidth, m_ShadowSettings.directionalShadowAtlasHeight);
                }

                SetupShadowCasterConstants(cmd, ref shadowLight, proj, shadowResolution);
                RenderShadowSlice(cmd, ref context, ref m_CascadeSlices[cascadeIndex], proj, view, settings);
            }

            if (success)
            {
                m_DirectionalShadowmapQuality = (m_ShadowSettings.directionalShadowQuality != LightShadows.Soft) ? LightShadows.Hard : light.shadows;

                // In order to avoid shader variants explosion we only do hard shadows when sampling shadowmap in the lit pass.
                // GLES2 platform is forced to hard single cascade shadows.
                if (!m_ShadowSettings.screenSpace)
                {
                    m_DirectionalShadowmapQuality = LightShadows.Hard;
                }

                SetupDirectionalShadowReceiverConstants(cmd, shadowLight, ref context);
            }

            context.ExecuteCommandBuffer(cmd);
            CommandBufferPool.Release(cmd);
            return(success);
        }
示例#26
0
        /// <inheritdoc/>
        public override void Execute(ScriptableRenderer renderer, ScriptableRenderContext context, ref RenderingData renderingData)
        {
            if (renderer == null)
            {
                throw new ArgumentNullException("renderer");
            }

            if (!renderingData.shadowData.supportsDeepShadowMaps)
            {
                return;
            }
            LightData lightData        = renderingData.lightData;
            int       shadowLightIndex = lightData.mainLightIndex;

            if (shadowLightIndex == -1)
            {
                return;
            }


            VisibleLight shadowLight = lightData.visibleLights[shadowLightIndex];
            ShadowData   shadowData  = renderingData.shadowData;

            if (!GetVPMatrix(shadowLight.light))
            {
                return;
            }

            if (null == _ResetCompute)
            {
                _ResetCompute     = renderer.GetCompute(ComputeHandle.ResetDeepShadowDataCompute);
                KernelResetBuffer = _ResetCompute.FindKernel("KernelResetBuffer");
            }

            CommandBuffer cmd = CommandBufferPool.Get(k_RenderDeepShadowCaster);

            using (new ProfilingSample(cmd, k_RenderDeepShadowCaster))
            {
                int deepShadowMapsSize  = shadowData.deepShadowMapsSize;
                int deepShadowMapsDepth = shadowData.deepShadowMapsDepth;
                // Reset
                cmd.SetComputeBufferParam(_ResetCompute, KernelResetBuffer, "_CountBuffer", _CountBuffer);
                cmd.SetComputeBufferParam(_ResetCompute, KernelResetBuffer, "_DataBuffer", _DataBuffer);
                cmd.SetComputeIntParam(_ResetCompute, "_DeepShadowMapSize", deepShadowMapsSize);
                cmd.SetComputeIntParam(_ResetCompute, "_DeepShadowMapDepth", deepShadowMapsDepth);
                cmd.DispatchCompute(_ResetCompute, KernelResetBuffer, deepShadowMapsSize / 8, deepShadowMapsSize / 8, 1);

                _Temp = RenderTexture.GetTemporary(deepShadowMapsSize, deepShadowMapsSize, 0, RenderTextureFormat.R8); //Without rt, the second row of the vp matrix is negated

                // Cast
                SetRenderTarget(cmd, _Temp, RenderBufferLoadAction.DontCare, RenderBufferStoreAction.DontCare,
                                ClearFlag.Color, Color.black, TextureDimension.Tex2D);
                cmd.SetViewport(new Rect(Vector2.zero, Vector2.one * deepShadowMapsSize));

                Vector4 shadowBias = ShadowUtils.GetShadowBias(ref shadowLight, shadowLightIndex, ref shadowData, _ProjMatrix, shadowData.deepShadowMapsSize);
                ShadowUtils.SetupShadowCasterConstantBuffer(cmd, ref shadowLight, shadowBias);

                cmd.SetViewProjectionMatrices(_ViewMatrix, _ProjMatrix);
                cmd.SetRandomWriteTarget(1, _CountBuffer);
                cmd.SetRandomWriteTarget(2, _DataBuffer);
                cmd.SetGlobalInt("_DeepShadowMapSize", deepShadowMapsSize);
                cmd.SetGlobalInt("_DeepShadowMapDepth", deepShadowMapsDepth);

                context.ExecuteCommandBuffer(cmd);
                cmd.Clear();

                //foreach (var r in _Renderers)
                //{
                //    for (int i = 0, imax = r.sharedMaterials.Length; i < imax; i++)
                //    {
                //        cmd.DrawRenderer(r, r.sharedMaterials[i], i, r.sharedMaterials[i].FindPass("DeepShadowCaster"));
                //    }
                //}

                ShadowSliceData slice = new ShadowSliceData()
                {
                    offsetX    = 0,
                    offsetY    = 0,
                    resolution = deepShadowMapsSize,
                };

                cmd.SetGlobalMatrix("_DeepShadowMapsWorldToShadow", _DeepShadowMatrix);
                DrawShadowsSettings settings = new DrawShadowsSettings(renderingData.cullResults, shadowLightIndex);
                settings.splitData.cullingSphere = _CullingSphere;

                cmd.EnableShaderKeyword("_DEEP_SHADOW_CASTER");
                cmd.SetGlobalInt("_ShadowCasterZWrite", 0);
                ShadowUtils.RenderShadowSlice(cmd, ref context, ref slice, ref settings, _ProjMatrix, _ViewMatrix);
                cmd.DisableShaderKeyword("_DEEP_SHADOW_CASTER");
                cmd.SetGlobalInt("_ShadowCasterZWrite", 1);

                context.ExecuteCommandBuffer(cmd);
                cmd.Clear();

                // For Resolve
                SetupDeepShadowMapResolverConstants(cmd, ref shadowData, shadowLight);
                cmd.ClearRandomWriteTargets();
            }

            context.ExecuteCommandBuffer(cmd);
            CommandBufferPool.Release(cmd);
        }
示例#27
0
            override public void Update(FrameId frameId, ScriptableRenderContext renderContext, CullResults cullResults, VisibleLight[] lights)
            {
                var profilingSample = new Utilities.ProfilingSample("Shadowmap" + m_TexSlot, renderContext);

                if (!string.IsNullOrEmpty(m_ShaderKeyword))
                {
                    var cb = new CommandBuffer();
                    cb.name = "Shadowmap.EnableShadowKeyword";
                    cb.EnableShaderKeyword(m_ShaderKeyword);
                    renderContext.ExecuteCommandBuffer(cb);
                    cb.Dispose();
                }

                // loop for generating each individual shadowmap
                uint   curSlice = uint.MaxValue;
                Bounds bounds;
                DrawShadowsSettings dss = new DrawShadowsSettings(cullResults, 0);

                for (uint i = 0; i < m_ActiveEntriesCount; ++i)
                {
                    if (!cullResults.GetShadowCasterBounds(m_EntryCache[i].key.visibleIdx, out bounds))
                    {
                        continue;
                    }

                    var  cb         = new CommandBuffer();
                    uint entrySlice = m_EntryCache[i].current.slice;
                    if (entrySlice != curSlice)
                    {
                        Debug.Assert(curSlice == uint.MaxValue || entrySlice >= curSlice, "Entries in the entry cache are not ordered in slice order.");
                        cb.name = "Shadowmap.Update.Slice" + entrySlice;

                        if (curSlice != uint.MaxValue)
                        {
                            PostUpdate(frameId, cb, curSlice);
                        }
                        curSlice = entrySlice;
                        PreUpdate(frameId, cb, curSlice);
                    }

                    cb.name = "Shadowmap.Update - slice: " + curSlice + ", vp.x: " + m_EntryCache[i].current.viewport.x + ", vp.y: " + m_EntryCache[i].current.viewport.y + ", vp.w: " + m_EntryCache[i].current.viewport.width + ", vp.h: " + m_EntryCache[i].current.viewport.height;
                    cb.SetViewport(m_EntryCache[i].current.viewport);
                    cb.SetViewProjectionMatrices(m_EntryCache[i].current.view, m_EntryCache[i].current.proj);
                    cb.SetGlobalVector("g_vLightDirWs", m_EntryCache[i].current.lightDir);
                    renderContext.ExecuteCommandBuffer(cb);
                    cb.Dispose();

                    dss.lightIndex = m_EntryCache[i].key.visibleIdx;
                    dss.splitData  = m_EntryCache[i].current.splitData;
                    renderContext.DrawShadows(ref dss); // <- if this was a call on the commandbuffer we would get away with using just once commandbuffer for the entire shadowmap, instead of one per face
                }

                // post update
                if (!string.IsNullOrEmpty(m_ShaderKeyword))
                {
                    var cb = new CommandBuffer();
                    cb.name = "Shadowmap.DisableShaderKeyword";
                    cb.DisableShaderKeyword(m_ShaderKeyword);
                    renderContext.ExecuteCommandBuffer(cb);
                    cb.Dispose();
                }

                m_ActiveEntriesCount = 0;

                profilingSample.Dispose();
            }
示例#28
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
        }
示例#29
0
    void RenderShadows(ScriptableRenderContext context)
    {
        int split;   //split to N*N tiles

        if (shadowTileCount <= 1)
        {
            split = 1;
        }
        else if (shadowTileCount <= 4)
        {
            split = 2;
        }
        else if (shadowTileCount <= 9)
        {
            split = 3;
        }
        else
        {
            split = 4;
        }

        float tileSize  = shadowMapSize / split;  //maximum light = 16
        float tileScale = 1f / split;

        globalShadowData.x = tileScale;

        shadowMap = SetShadowRenderTarget();

        shadowBuffer.BeginSample("Render Shadows");

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

        int  tileIndex   = 0;
        bool hardShadows = false;
        bool softShadows = false;

        for (int i = mainLightExists ? 1 : 0; i < cull.visibleLights.Count; i++)
        {
            if (i == maxVisibleLights)
            {
                break;
            }
            //shadowStrength <=0 indicates the light needs no shadowmap
            if (shadowData[i].x <= 0f)
            {
                continue;
            }

            //render shadowMap for light i
            Matrix4x4       viewMatrix, projectionMatrix;
            ShadowSplitData splitData;

            bool validShadows;
            if (shadowData[i].z > 0f)
            {
                validShadows =
                    cull.ComputeDirectionalShadowMatricesAndCullingPrimitives(
                        i, 0, 1, Vector3.right, (int)tileSize,
                        cull.visibleLights[i].light.shadowNearPlane,
                        out viewMatrix, out projectionMatrix, out splitData);
            }
            else
            {
                validShadows = cull.ComputeSpotShadowMatricesAndCullingPrimitives(
                    i, out viewMatrix, out projectionMatrix, out splitData);
            }

            if (!validShadows)
            {
                shadowData[i].x = 0f;
                continue;
            }


            Vector2 tileOffset = ConfigureShadowTile(tileIndex, split, tileSize);
            shadowData[i].z = tileOffset.x * tileScale;
            shadowData[i].w = tileOffset.y * tileScale;

            shadowBuffer.SetViewProjectionMatrices(viewMatrix, projectionMatrix);

            shadowBuffer.SetGlobalFloat(
                shadowBiasId, cull.visibleLights[i].light.shadowBias
                ); // shadow bias

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

            var shadowSettings = new DrawShadowsSettings(cull, i);
            shadowSettings.splitData.cullingSphere = splitData.cullingSphere;
            context.DrawShadows(ref shadowSettings);

            CalculateWorldToShadowMatrix(ref viewMatrix, ref projectionMatrix,
                                         out worldToShadowMatrices[i]);

            tileIndex += 1;

            //for generate shader keyword of all soft/all hard shadows
            if (shadowData[i].y <= 0f)
            {
                hardShadows = true;
            }
            else
            {
                softShadows = true;
            }
        }

        shadowBuffer.DisableScissorRect();

        //sample shadowMap
        shadowBuffer.SetGlobalTexture(shadowMapId, shadowMap);

        shadowBuffer.SetGlobalMatrixArray(worldToShadowMatricesId, worldToShadowMatrices);
        //_ShadowData , including shadow strength
        shadowBuffer.SetGlobalVectorArray(shadowDataId, shadowData);


        //soft shadows, tent filter inputs
        float invShadowMapSize = 1f / shadowMapSize;

        shadowBuffer.SetGlobalVector(
            shadowMapSizeId, new Vector4(
                invShadowMapSize, invShadowMapSize, shadowMapSize, shadowMapSize
                )
            );

        CoreUtils.SetKeyword(shadowBuffer, shadowsHardKeyword, hardShadows);
        CoreUtils.SetKeyword(shadowBuffer, shadowsSoftKeyword, softShadows);

        shadowBuffer.EndSample("Render Shadows");
        context.ExecuteCommandBuffer(shadowBuffer);
        shadowBuffer.Clear();
    }
示例#30
0
    //Starts Rendering Part
    public static void Render(ScriptableRenderContext context, IEnumerable <Camera> cameras)
    {
        //For shadowmapping, the matrices from the light's point of view
        Matrix4x4 view             = Matrix4x4.identity;
        Matrix4x4 proj             = Matrix4x4.identity;
        bool      successShadowMap = false;

        foreach (Camera camera in cameras)
        {
            bool isSceneViewCam = camera.cameraType == CameraType.SceneView;
            //************************** UGUI Geometry on scene view *************************
            #if UNITY_EDITOR
            if (isSceneViewCam)
            {
                ScriptableRenderContext.EmitWorldGeometryForSceneView(camera);
            }
            #endif

            //************************** Culling ****************************************
            ScriptableCullingParameters cullingParams;
            if (!CullResults.GetCullingParameters(camera, out cullingParams))
            {
                continue;
            }
            CullResults cull = new CullResults();
            CullResults.Cull(ref cullingParams, context, ref cull);

            //************************** Lighting Variables *****************************
            CommandBuffer cmdLighting = new CommandBuffer();
            cmdLighting.name = "(" + camera.name + ")" + "Lighting variable";
            int   mainLightIndex = -1;
            Light mainLight      = null;

            Vector4[] lightPositions = new Vector4[8];
            Vector4[] lightColors    = new Vector4[8];
            Vector4[] lightAttn      = new Vector4[8];
            Vector4[] lightSpotDir   = new Vector4[8];

            //Initialise values
            for (int i = 0; i < 8; i++)
            {
                lightPositions[i] = new Vector4(0.0f, 0.0f, 1.0f, 0.0f);
                lightColors[i]    = Color.black;
                lightAttn[i]      = new Vector4(0.0f, 1.0f, 0.0f, 1.0f);
                lightSpotDir[i]   = new Vector4(0.0f, 0.0f, 1.0f, 0.0f);
            }

            for (int i = 0; i < cull.visibleLights.Count; i++)
            {
                VisibleLight light = cull.visibleLights[i];

                if (mainLightIndex == -1) //Directional light
                {
                    if (light.lightType == LightType.Directional)
                    {
                        Vector4 dir = light.localToWorld.GetColumn(2);
                        lightPositions[0] = new Vector4(-dir.x, -dir.y, -dir.z, 0);
                        lightColors[0]    = light.light.color;

                        float lightRangeSqr                 = light.range * light.range;
                        float fadeStartDistanceSqr          = 0.8f * 0.8f * lightRangeSqr;
                        float fadeRangeSqr                  = (fadeStartDistanceSqr - lightRangeSqr);
                        float oneOverFadeRangeSqr           = 1.0f / fadeRangeSqr;
                        float lightRangeSqrOverFadeRangeSqr = -lightRangeSqr / fadeRangeSqr;
                        float quadAtten = 25.0f / lightRangeSqr;
                        lightAttn[0] = new Vector4(quadAtten, oneOverFadeRangeSqr, lightRangeSqrOverFadeRangeSqr, 1.0f);

                        cmdLighting.SetGlobalVector("_LightColor0", lightColors[0]);
                        cmdLighting.SetGlobalVector("_WorldSpaceLightPos0", lightPositions[0]);

                        mainLight      = light.light;
                        mainLightIndex = i;
                    }
                }
                else
                {
                    continue;//so far just do only 1 directional light
                }
            }

            cmdLighting.SetGlobalVectorArray("unity_LightPosition", lightPositions);
            cmdLighting.SetGlobalVectorArray("unity_LightColor", lightColors);
            cmdLighting.SetGlobalVectorArray("unity_LightAtten", lightAttn);
            cmdLighting.SetGlobalVectorArray("unity_SpotDirection", lightSpotDir);

            context.ExecuteCommandBuffer(cmdLighting);
            cmdLighting.Release();

            //************************** Draw Settings ************************************
            FilterRenderersSettings filterSettings = new FilterRenderersSettings(true);

            DrawRendererSettings drawSettingsDefault = new DrawRendererSettings(camera, passNameDefault);
            drawSettingsDefault.rendererConfiguration = renderConfig;
            drawSettingsDefault.flags = DrawRendererFlags.EnableDynamicBatching;
            drawSettingsDefault.SetShaderPassName(5, m_UnlitPassName);

            DrawRendererSettings drawSettingsBase = new DrawRendererSettings(camera, passNameBase);
            drawSettingsBase.flags = DrawRendererFlags.EnableDynamicBatching;
            drawSettingsBase.rendererConfiguration = renderConfig;

            DrawRendererSettings drawSettingsAdd = new DrawRendererSettings(camera, passNameAdd);
            drawSettingsAdd.flags = DrawRendererFlags.EnableDynamicBatching;
            drawSettingsAdd.rendererConfiguration = renderConfig;

            DrawRendererSettings drawSettingsDepth = new DrawRendererSettings(camera, passNameShadow);
            drawSettingsDepth.flags = DrawRendererFlags.EnableDynamicBatching;
            //drawSettingsBase.rendererConfiguration = renderConfig;

            //************************** Set TempRT ************************************
            CommandBuffer cmdTempId = new CommandBuffer();
            cmdTempId.name = "(" + camera.name + ")" + "Setup TempRT";

            //Depth
            RenderTextureDescriptor depthRTDesc = new RenderTextureDescriptor(camera.pixelWidth, camera.pixelHeight);
            depthRTDesc.colorFormat     = m_DepthFormat;
            depthRTDesc.depthBufferBits = depthBufferBits;
            cmdTempId.GetTemporaryRT(m_DepthRTid, depthRTDesc, FilterMode.Bilinear);

            //Color
            RenderTextureDescriptor colorRTDesc = new RenderTextureDescriptor(camera.pixelWidth, camera.pixelHeight);
            colorRTDesc.colorFormat       = m_ColorFormat;
            colorRTDesc.depthBufferBits   = depthBufferBits; //have depth because we don't want to ruin the _CameraDepthTexture
            colorRTDesc.sRGB              = true;
            colorRTDesc.msaaSamples       = 1;
            colorRTDesc.enableRandomWrite = false;
            cmdTempId.GetTemporaryRT(m_ColorRTid, colorRTDesc, FilterMode.Bilinear);

            //Shadow
            RenderTextureDescriptor shadowRTDesc = new RenderTextureDescriptor(m_ShadowRes, m_ShadowRes);
            shadowRTDesc.colorFormat       = m_ShadowFormat;
            shadowRTDesc.depthBufferBits   = depthBufferBits; //have depth because it is also a depth texture
            shadowRTDesc.msaaSamples       = 1;
            shadowRTDesc.enableRandomWrite = false;
            cmdTempId.GetTemporaryRT(m_ShadowMapLightid, shadowRTDesc, FilterMode.Bilinear);//depth per light

            //ScreenSpaceShadowMap
            RenderTextureDescriptor shadowMapRTDesc = new RenderTextureDescriptor(camera.pixelWidth, camera.pixelHeight);
            shadowMapRTDesc.colorFormat       = m_ShadowMapFormat;
            shadowMapRTDesc.depthBufferBits   = 0;
            shadowMapRTDesc.msaaSamples       = 1;
            shadowMapRTDesc.enableRandomWrite = false;
            cmdTempId.GetTemporaryRT(m_ShadowMapid, shadowMapRTDesc, FilterMode.Bilinear);//screen space shadow

            context.ExecuteCommandBuffer(cmdTempId);
            cmdTempId.Release();

            //************************** Do shadow? ************************************
            Bounds bounds;
            bool   doShadow = cull.GetShadowCasterBounds(mainLightIndex, out bounds);

            //************************** Shadow Mapping ************************************
            if (doShadow && !isSceneViewCam)
            {
                DrawShadowsSettings shadowSettings = new DrawShadowsSettings(cull, mainLightIndex);

                successShadowMap = cull.ComputeDirectionalShadowMatricesAndCullingPrimitives(mainLightIndex,
                                                                                             0, 1, new Vector3(1, 0, 0),
                                                                                             m_ShadowRes, mainLight.shadowNearPlane, out view, out proj,
                                                                                             out shadowSettings.splitData);

                CommandBuffer cmdShadow = new CommandBuffer();
                cmdShadow.name = "(" + camera.name + ")" + "Shadow Mapping";

                cmdShadow.SetRenderTarget(m_ShadowMapLight);
                cmdShadow.ClearRenderTarget(true, true, Color.black);

                //Change the view to light's point of view
                cmdShadow.SetViewport(new Rect(0, 0, m_ShadowRes, m_ShadowRes));
                cmdShadow.EnableScissorRect(new Rect(4, 4, m_ShadowRes - 8, m_ShadowRes - 8));
                cmdShadow.SetViewProjectionMatrices(view, proj);

                context.ExecuteCommandBuffer(cmdShadow);
                cmdShadow.Clear();

                //Render Shadowmap
                context.DrawShadows(ref shadowSettings);

                cmdShadow.DisableScissorRect();
                cmdShadow.SetGlobalTexture(m_ShadowMapLightid, m_ShadowMapLight);
                context.ExecuteCommandBuffer(cmdShadow);
                cmdShadow.Clear();
                cmdShadow.Release();
            }

            //************************** Camera Parameters ************************************
            context.SetupCameraProperties(camera);

            //************************** Depth (for CameraDepthTexture) ************************************
            CommandBuffer cmdDepthOpaque = new CommandBuffer();
            cmdDepthOpaque.name = "(" + camera.name + ")" + "Make CameraDepthTexture";

            cmdDepthOpaque.SetRenderTarget(m_DepthRT);
            cmdDepthOpaque.ClearRenderTarget(true, true, Color.black);
            context.ExecuteCommandBuffer(cmdDepthOpaque);
            cmdDepthOpaque.Clear();

            filterSettings.renderQueueRange = RenderQueueRange.opaque;
            drawSettingsDepth.sorting.flags = SortFlags.CommonOpaque;
            context.DrawRenderers(cull.visibleRenderers, ref drawSettingsDepth, filterSettings);

            cmdDepthOpaque.SetGlobalTexture(m_DepthRTid, m_DepthRT);
            context.ExecuteCommandBuffer(cmdDepthOpaque);
            cmdDepthOpaque.Release();

            //************************** Screen Space Shadow ************************************
            if (doShadow)
            {
                CommandBuffer cmdShadow2 = new CommandBuffer();
                cmdShadow2.name = "(" + camera.name + ")" + "Screen Space Shadow";

                //Bias
                if (mainLight != null)
                {
                    float sign = (SystemInfo.usesReversedZBuffer) ? 1.0f : -1.0f;
                    if (isSceneViewCam)
                    {
                        sign = -sign * 0.01f;
                    }
                    float bias = mainLight.shadowBias * proj.m22 * sign;

                    cmdShadow2.SetGlobalFloat("_ShadowBias", bias);
                }

                //Shadow Transform
                if (successShadowMap)
                {
                    cmdShadow2.EnableShaderKeyword("SHADOWS_SCREEN");
                    cmdShadow2.EnableShaderKeyword("LIGHTMAP_SHADOW_MIXING");

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

                    Matrix4x4 WorldToShadow = proj * view;

                    float f = 0.5f;

                    var textureScaleAndBias = Matrix4x4.identity;
                    textureScaleAndBias.m00 = f;
                    textureScaleAndBias.m11 = f;
                    textureScaleAndBias.m22 = f;
                    textureScaleAndBias.m03 = f;
                    textureScaleAndBias.m23 = f;
                    textureScaleAndBias.m13 = f;

                    WorldToShadow = textureScaleAndBias * WorldToShadow;

                    cmdShadow2.SetGlobalMatrix("_WorldToShadow", WorldToShadow);
                    cmdShadow2.SetGlobalFloat("_ShadowStrength", mainLight.shadowStrength);
                }

                //Render the screen-space shadow
                cmdShadow2.Blit(m_ShadowMap, m_ShadowMap, m_ScreenSpaceShadowsMaterial);
                cmdShadow2.SetGlobalTexture(m_ShadowMapid, m_ShadowMap);

                context.ExecuteCommandBuffer(cmdShadow2);
                cmdShadow2.Release();
            }

            //************************** Clear ************************************
            CommandBuffer cmd = new CommandBuffer();
            cmd.name = "(" + camera.name + ")" + "Clear Flag";

            cmd.SetRenderTarget(m_ColorRT);
            ClearFlag(cmd, camera, camera.backgroundColor);

            context.ExecuteCommandBuffer(cmd);
            cmd.Release();

            //************************** Skybox ************************************
            if (camera.clearFlags == CameraClearFlags.Skybox)
            {
                context.DrawSkybox(camera);
            }

            //************************** Opaque ************************************
            filterSettings.renderQueueRange = RenderQueueRange.opaque;

            // DEFAULT pass, draw shaders without a pass name
            drawSettingsDefault.sorting.flags = SortFlags.CommonOpaque;
            context.DrawRenderers(cull.visibleRenderers, ref drawSettingsDefault, filterSettings);

            // BASE pass
            drawSettingsBase.sorting.flags = SortFlags.CommonOpaque;
            context.DrawRenderers(cull.visibleRenderers, ref drawSettingsBase, filterSettings);

            // ADD pass
            drawSettingsAdd.sorting.flags = SortFlags.CommonOpaque;
            context.DrawRenderers(cull.visibleRenderers, ref drawSettingsAdd, filterSettings);

            //************************** Blit to Camera Target ************************************
            // so that reflection probes will work + screen view buttons
            CommandBuffer cmdColorOpaque = new CommandBuffer();
            cmdColorOpaque.name = "(" + camera.name + ")" + "After opaque";

            //This blit is necessary for Windows...It makes sure the Z is correct for transparent objects
            cmdColorOpaque.Blit(m_ColorRT, BuiltinRenderTextureType.CameraTarget);
            cmdColorOpaque.SetRenderTarget(m_ColorRT);

            //"Grab" pass
            cmdColorOpaque.SetGlobalTexture(m_GrabOpaqueRTid, m_ColorRT);

            context.ExecuteCommandBuffer(cmdColorOpaque);
            cmdColorOpaque.Release();

            //************************** Transparent ************************************
            filterSettings.renderQueueRange = RenderQueueRange.transparent;

            // DEFAULT pass
            drawSettingsDefault.sorting.flags = SortFlags.CommonTransparent;
            context.DrawRenderers(cull.visibleRenderers, ref drawSettingsDefault, filterSettings);

            // BASE pass
            drawSettingsBase.sorting.flags = SortFlags.CommonTransparent;
            context.DrawRenderers(cull.visibleRenderers, ref drawSettingsBase, filterSettings);

            //************************** Blit to Camera Target ************************************
            // so that reflection probes will work + screen view buttons
            CommandBuffer cmdColor = new CommandBuffer();
            cmdColor.name = "(" + camera.name + ")" + "After transparent";
            cmdColor.Blit(m_ColorRT, BuiltinRenderTextureType.CameraTarget);
            cmdColor.SetRenderTarget(m_ColorRT);
            context.ExecuteCommandBuffer(cmdColor);
            cmdColor.Release();

            //************************** Post-processing ************************************
            m_CameraPostProcessLayer = camera.GetComponent <PostProcessLayer>();
            if (m_CameraPostProcessLayer != null && m_CameraPostProcessLayer.enabled)
            {
                CommandBuffer cmdpp = new CommandBuffer();
                cmdpp.name = "(" + camera.name + ")" + "Post-processing";

                m_PostProcessRenderContext.Reset();
                m_PostProcessRenderContext.camera       = camera;
                m_PostProcessRenderContext.source       = m_ColorRT;
                m_PostProcessRenderContext.sourceFormat = m_ColorFormat;
                m_PostProcessRenderContext.destination  = BuiltinRenderTextureType.CameraTarget;
                m_PostProcessRenderContext.command      = cmdpp;
                m_PostProcessRenderContext.flip         = camera.targetTexture == null;
                m_CameraPostProcessLayer.Render(m_PostProcessRenderContext);

                //Target is already CameraTarget

                context.ExecuteCommandBuffer(cmdpp);
                cmdpp.Release();
            }

            //************************** Scene View Fix ************************************
            #if UNITY_EDITOR
            if (isSceneViewCam)     //Copy depth to backbuffer's depth buffer
            {
                CommandBuffer cmdSceneDepth = new CommandBuffer();
                cmdSceneDepth.name = "(" + camera.name + ")" + "Copy Depth to CameraTarget";
                cmdSceneDepth.Blit(m_DepthRT, BuiltinRenderTextureType.CameraTarget, m_CopyDepthMaterial);
                context.ExecuteCommandBuffer(cmdSceneDepth);
                cmdSceneDepth.Release();
            }
            #endif

            //************************** Clean Up ************************************
            CommandBuffer cmdclean = new CommandBuffer();
            cmdclean.name = "(" + camera.name + ")" + "Clean Up";
            cmdclean.ReleaseTemporaryRT(m_ColorRTid);
            cmdclean.ReleaseTemporaryRT(m_DepthRTid);
            cmdclean.ReleaseTemporaryRT(m_ShadowMapid);
            cmdclean.ReleaseTemporaryRT(m_ShadowMapLightid);
            context.ExecuteCommandBuffer(cmdclean);
            cmdclean.Release();

            context.Submit();
        }
    }