Example #1
0
    public MyPipeline(bool dynamicBatching, bool instancing,
                      int shadowMapSize, float shadowDistance,
                      int shadowCascades, Vector3 shadowCascadeSplit,
                      MyPostProcessingStack defaultStack, float renderScale)
    {
        GraphicsSettings.lightsUseLinearIntensity = true;
        if (SystemInfo.usesReversedZBuffer)
        {
            worldToShadowCascadeMatrices[4].m33 = 1f;
        }

        if (dynamicBatching)
        {
            drawFlags = DrawRendererFlags.EnableDynamicBatching;
        }
        if (instancing)
        {
            drawFlags = DrawRendererFlags.EnableInstancing;
        }
        this.shadowMapSize      = shadowMapSize;
        this.shadowDistance     = shadowDistance;
        this.shadowCascades     = shadowCascades;
        this.shadowCascadeSplit = shadowCascadeSplit;
        this.defaultStack       = defaultStack;
        this.renderScale        = renderScale;
    }
Example #2
0
    public MyPipeline(bool dynamicBatching, bool instanceing, MyPostProcessingStack defaultStack, Texture2D ditherTexture, float ditherAnimationSpeed, int shadowMapSize, float shadowDistance, float shadowFadeRange, int shadowCascades, Vector3 shadowCascadeSplit, float renderScale, int msaaSamples, bool allowHDR)
    {
        GraphicsSettings.lightsUseLinearIntensity = true;
        if (SystemInfo.usesReversedZBuffer)
        {
            worldToShadowCascadeMatrices[4].m33 = 1f;
        }
        if (dynamicBatching)
        {
            drawFlags = DrawRendererFlags.EnableDynamicBatching;
        }

        if (instanceing)
        {
            drawFlags |= DrawRendererFlags.EnableInstancing;
        }
        this.ditherTexture = ditherTexture;
        if (ditherAnimationSpeed > 0f && Application.isPlaying)
        {
            ConfigureDitherAnimation(ditherAnimationSpeed);
        }
        this.shadowMapSize           = shadowMapSize;
        this.shadowDistance          = shadowDistance;
        globalShadowData.y           = 1f / shadowFadeRange;
        this.shadowCascades          = shadowCascades;
        this.shadowCascadeSplit      = shadowCascadeSplit;
        this.defaultStack            = defaultStack;
        this.renderScale             = renderScale;
        this.allowHDR                = allowHDR;
        QualitySettings.antiAliasing = msaaSamples;
        this.msaaSamples             = Mathf.Max(QualitySettings.antiAliasing, 1);
#if UNITY_EDITOR
        Lightmapping.SetDelegate(lightmappingLightsDelegate);
#endif
    }
    public MyPipeline(bool dynamicBatching, bool instancing, MyPostProcessingStack _defaultStack,
                      Texture2D _ditherTexture, float _ditherAnimationSpeed, int _shadowMapSize, float _shadowDistance
                      , float _shadowFadeRange, int _shadowCascades, Vector3 _shadowCascadeSplit, float _renderScale
                      , int _msaaSamples, bool _allowHDR, bool _syncGameCamera)
    {
        //Unity 认为光的强度是在伽马空间中定义的,即使我们是在线性空间中工作。
        GraphicsSettings.lightsUseLinearIntensity = true;

        //如果Z相反 阴影的z最远是1
        if (SystemInfo.usesReversedZBuffer)
        {
            worldToShadowCascadeMatrices[4].m33 = 1f;
        }

        if (dynamicBatching)
        {
            drawFlags = DrawRendererFlags.EnableDynamicBatching;
        }

        ditherTexture = _ditherTexture;
        if (_ditherAnimationSpeed > 0f)
        {
            ConfigureDitherAnimation(_ditherAnimationSpeed);
        }

        if (instancing)
        {
            drawFlags |= DrawRendererFlags.EnableInstancing;
        }

        defaultStack = _defaultStack;

        shadowMapSize      = _shadowMapSize;
        shadowDistance     = _shadowDistance;
        globalShadowData.y = 1f / _shadowFadeRange;
        shadowCascades     = _shadowCascades;
        shadowCascadeSplit = _shadowCascadeSplit;
        renderScale        = _renderScale;
        //设置msaa 如果硬件不支持 则为自动回退为1
        QualitySettings.antiAliasing = _msaaSamples;
        msaaSamples = Mathf.Max(QualitySettings.antiAliasing, 1);
        allowHDR    = _allowHDR;

#if UNITY_EDITOR
        if (SceneView.onSceneGUIDelegate != null)
        {
            SceneView.onSceneGUIDelegate -= OnSceneView;
        }

        if (_syncGameCamera)
        {
            SceneView.onSceneGUIDelegate += OnSceneView;
        }
#endif

#if UNITY_EDITOR
        Lightmapping.SetDelegate(lightmappingLightDelegate);
#endif
    }
Example #4
0
    public MyPipeline(bool dynamicBatching, bool instancing, MyPostProcessingStack defaultStack, int shadowMapSize, float shadowDistance,
                      int shadowCascades, Vector3 shadowCascadeSplit, float renderScale, int msaaSamples, bool allowHDR)
    {
        // Unity默认光强度是在Gamma空间中定义,即使我们工作在线性空间
        // 我们需要指定Unity将光强度理解为线性空间中的值
        GraphicsSettings.lightsUseLinearIntensity = true;

        if (SystemInfo.usesReversedZBuffer)
        {
            worldToShadowCascadeMatrices[4].m33 = 1f;
        }

        if (dynamicBatching)
        {
            // 开启动态批处理
            drawFlags = DrawRendererFlags.EnableDynamicBatching;
        }
        if (instancing)
        {
            // 开启GPU实例化
            // 如果同时开启动态批处理,Unity优先使用GPU实例化
            drawFlags |= DrawRendererFlags.EnableInstancing;
        }

        this.defaultStack = defaultStack;

        this.shadowMapSize      = shadowMapSize;
        this.shadowDistance     = shadowDistance;
        this.shadowCascades     = shadowCascades;
        this.shadowCascadeSplit = shadowCascadeSplit;

        this.renderScale = renderScale;

        // QualitySettings会处理平台或者硬件不支持的情况,所以把值赋过去再取回。如果不支持MSAA,取回的值是0
        QualitySettings.antiAliasing = msaaSamples;
        this.msaaSamples             = Mathf.Max(QualitySettings.antiAliasing, 1);

        this.allowHDR = allowHDR;
    }
Example #5
0
    /// <summary>
    /// 准备渲染时需要的数据
    /// </summary>
    private void perpareData()
    {
        //当前相机是否需要后处理
        var myPipelineCamera = m_camera.GetComponent <MyPipelineCamera>();

        m_activeStack = myPipelineCamera ? myPipelineCamera.postProcessingStack : m_rpp.defaultStack;

        //根据是否开启HDR选用渲染纹理格式
        m_format = m_rpp.allowHDR && m_camera.allowHDR ? RenderTextureFormat.DefaultHDR : RenderTextureFormat.Default;

        //获取多重采样抗锯齿参数
        //如果Msaa不被支持返回0
        QualitySettings.antiAliasing = m_rpp.msaa;
        m_rpp.msaa      = Mathf.Max(QualitySettings.antiAliasing, 1);
        m_renderSamples = m_camera.allowMSAA ? m_rpp.msaa : 1;

        //缩放分辨率
        m_scaledRendering = (m_rpp.renderScale <1.0f || m_rpp.renderScale> 1.0f) && m_camera.cameraType == CameraType.Game;
        m_renderSize.x    = m_camera.pixelWidth;
        m_renderSize.y    = m_camera.pixelHeight;
        if (m_scaledRendering)
        {
            m_renderSize.x = (int)(m_renderSize.x * m_rpp.renderScale);
            m_renderSize.y = (int)(m_renderSize.y * m_rpp.renderScale);
        }

        //判断是否渲染到纹理
        m_renderToTexture = m_scaledRendering || m_renderSamples > 1 || m_activeStack;

        //判断是否需要深度贴图
        m_needsDepth = m_activeStack && m_activeStack.needsDepth;

        //如果开启多重采样,需要单独的一个Pass渲染深度
        m_needsDirectDepth   = m_needsDepth && m_renderSamples == 1;
        m_needsDepthOnlyPass = m_needsDepth && m_renderSamples > 1;
    }
    public void Render(ScriptableRenderContext context, Camera camera)
    {
        if (!CullResults.GetCullingParameters(camera, out var cullingParameters))
        {
            return;
        }

        cullingParameters.shadowDistance = Mathf.Min(shadowDistance, camera.farClipPlane);

#if UNITY_EDITOR
        if (camera.cameraType == CameraType.SceneView)
        {
            //将UI几何体发射到“场景”视图中以进行渲染。
            ScriptableRenderContext.EmitWorldGeometryForSceneView(camera);
        }
        else if (mainCamera == null && camera.cameraType == CameraType.Game && camera == Camera.main)
        {
            mainCamera = camera;
        }
#endif

        //CullResults cull = CullResults.Cull(ref cullingParameters, context);
        CullResults.Cull(ref cullingParameters, context, ref cull);

        if (cull.visibleLights.Count > 0)
        {
            ConfigureLights();
            if (mainLightExists)
            {
                RenderCascadedShadows(context);
            }
            else
            {
                cameraBuffer.DisableShaderKeyword(cascadedShadowsHardKeyword);
                cameraBuffer.DisableShaderKeyword(cascadedShadowsSoftKeyword);
            }

            if (shadowTileCount > 0)
            {
                RenderShadows(context);
            }
            else
            {
                cameraBuffer.DisableShaderKeyword(shadowsHardKeyword);
                cameraBuffer.DisableShaderKeyword(shadowsSoftKeyword);
            }
        }
        else
        {
            cameraBuffer.SetGlobalVector(lightIndicesOffsetAndCountID, Vector4.zero);
            cameraBuffer.DisableShaderKeyword(cascadedShadowsHardKeyword);
            cameraBuffer.DisableShaderKeyword(cascadedShadowsSoftKeyword);
            cameraBuffer.DisableShaderKeyword(shadowsHardKeyword);
            cameraBuffer.DisableShaderKeyword(shadowsSoftKeyword);
        }

        context.SetupCameraProperties(camera);

        var myPipelineCamera = camera.GetComponent <MyPipelineCamera>();
        MyPostProcessingStack activeStack = myPipelineCamera ? myPipelineCamera.PostProcessingStack : defaultStack;

        bool scaledRendering = renderScale != 1f && camera.cameraType == CameraType.Game;

        int renderWidth  = camera.pixelWidth;
        int renderHeight = camera.pixelHeight;
        if (scaledRendering)
        {
            renderWidth  = (int)(renderWidth * renderScale);
            renderHeight = (int)(renderHeight * renderScale);
        }

        int  renderSamples   = camera.allowMSAA ? msaaSamples : 1;
        bool renderToTexture = scaledRendering || renderSamples > 1 || activeStack;

        bool needsDepth = activeStack && activeStack.NeedsDepth;
        //如果MSAA != 1 , 则 主贴图需要 24位深度 用来ZTestWrite画
        bool needsDirectDepth = needsDepth && renderSamples == 1;
        //专门用DepthOnly 来画深度图
        bool needsDepthOnlyPass = needsDepth && renderSamples > 1;

        RenderTextureFormat format =
            allowHDR && camera.allowHDR ? RenderTextureFormat.DefaultHDR : RenderTextureFormat.Default;

        if (renderToTexture)
        {
            //需要深度进行处理的的时候  要单独的深度图   不让它进行MSAA
            //否则可以跟随主颜色进行MSAA
            cameraBuffer.GetTemporaryRT(cameraColorTextureID, renderWidth, renderHeight, needsDirectDepth ? 0 : 24
                                        , FilterMode.Bilinear, format, RenderTextureReadWrite.Default, renderSamples);

            if (needsDepth)
            {
                cameraBuffer.GetTemporaryRT(cameraDepthTextureID, renderWidth, renderHeight, 24
                                            , FilterMode.Point, RenderTextureFormat.Depth, RenderTextureReadWrite.Linear, 1);
            }

            if (needsDirectDepth)
            {
                cameraBuffer.SetRenderTarget(cameraColorTextureID, RenderBufferLoadAction.DontCare,
                                             RenderBufferStoreAction.Store, cameraDepthTextureID, RenderBufferLoadAction.DontCare,
                                             RenderBufferStoreAction.Store);
            }
            else
            {
                cameraBuffer.SetRenderTarget(cameraColorTextureID, RenderBufferLoadAction.DontCare,
                                             RenderBufferStoreAction.Store);
            }
        }


        CameraClearFlags clearFlags = camera.clearFlags;
        cameraBuffer.ClearRenderTarget((clearFlags & CameraClearFlags.Depth) != 0
                                       , (clearFlags & CameraClearFlags.Color) != 0, camera.backgroundColor);


        cameraBuffer.BeginSample("Render Camera");

        cameraBuffer.SetGlobalVectorArray(visibleLightColorsID, visibleLightColors);
        cameraBuffer.SetGlobalVectorArray(visibleLightDirectionsOrPositionsID, visibleLightDirectionsOrPositions);
        cameraBuffer.SetGlobalVectorArray(visibleLightAttenuationsID, visibleLightAttenuations);
        cameraBuffer.SetGlobalVectorArray(visibleLightSpotDirectionsID, visibleLightSpotDirections);
        cameraBuffer.SetGlobalVectorArray(visibleLightOcclusionMaskID, visibleLightOcclusionMasks);

        globalShadowData.z = 1f - cullingParameters.shadowDistance * globalShadowData.y;
        cameraBuffer.SetGlobalVector(globalShadowDataID, globalShadowData);
        context.ExecuteCommandBuffer(cameraBuffer);
        cameraBuffer.Clear();

        //这样就可以走SRP的SubShader 如果没有则都走
        //Shader SubShader Tags{"RenderPipeline"="MySRPPipeline"}
        //Shader.globalRenderPipeline = "MySRPPipeline";

        //我们必须通过提供相机和一个shader pass 作为draw setting的构造函数的参数。
        //这个相机用来设置排序和裁剪层级(culling layers),
        //而shader pass 控制使用那个shader pass进行渲染。
        //如果Pass未指定LightMode,Unity会自动将其设置为SRPDefaultUnlit
        var drawSettings = new DrawRendererSettings(camera, new ShaderPassName("SRPDefaultUnlit"))
        {
            flags = drawFlags,
            rendererConfiguration = RendererConfiguration.None
        };
        if (cull.visibleLights.Count > 0)
        {
            drawSettings.rendererConfiguration = RendererConfiguration.PerObjectLightIndices8;
        }

        drawSettings.rendererConfiguration |= RendererConfiguration.PerObjectReflectionProbes
                                              | RendererConfiguration.PerObjectLightmaps
                                              | RendererConfiguration.PerObjectLightProbe
                                              | RendererConfiguration.PerObjectLightProbeProxyVolume
                                              | RendererConfiguration.PerObjectShadowMask
                                              | RendererConfiguration.PerObjectOcclusionProbe
                                              | RendererConfiguration.PerObjectOcclusionProbeProxyVolume;

        drawSettings.sorting.flags = SortFlags.CommonOpaque;
        //因为 Unity 更喜欢将对象空间化地分组以减少overdraw
        var filterSettings = new FilterRenderersSettings(true)
        {
            renderQueueRange = RenderQueueRange.opaque
        };
        context.DrawRenderers(
            cull.visibleRenderers, ref drawSettings, filterSettings);


        context.DrawSkybox(camera);

        if (activeStack)
        {
            if (needsDepth)
            {
                if (needsDepthOnlyPass)
                {
                    var depthOnlyDrawSettings = new DrawRendererSettings(
                        camera, new ShaderPassName("DepthOnly"))
                    {
                        flags = drawFlags, sorting = { flags = SortFlags.CommonOpaque }
                    };


                    cameraBuffer.SetRenderTarget(cameraDepthTextureID, RenderBufferLoadAction.DontCare,
                                                 RenderBufferStoreAction.Store);
                    cameraBuffer.ClearRenderTarget(true, false, Color.clear);
                    context.ExecuteCommandBuffer(cameraBuffer);
                    cameraBuffer.Clear();
                    context.DrawRenderers(cull.visibleRenderers, ref depthOnlyDrawSettings, filterSettings);
                }
            }


            activeStack.RenderAfterOpaque(
                postProcessingBuffer, cameraColorTextureID, cameraDepthTextureID
                , renderWidth, renderHeight, renderSamples, format);
            context.ExecuteCommandBuffer(postProcessingBuffer);
            postProcessingBuffer.Clear();

            if (needsDirectDepth)
            {
                cameraBuffer.SetRenderTarget(
                    cameraColorTextureID, RenderBufferLoadAction.Load, RenderBufferStoreAction.Store
                    , cameraDepthTextureID, RenderBufferLoadAction.Load, RenderBufferStoreAction.Store);
            }
            else
            {
                cameraBuffer.SetRenderTarget(cameraColorTextureID, RenderBufferLoadAction.Load,
                                             RenderBufferStoreAction.Store);
            }

            context.ExecuteCommandBuffer(cameraBuffer);
            cameraBuffer.Clear();
        }


        drawSettings.sorting.flags      = SortFlags.CommonTransparent;
        filterSettings.renderQueueRange = RenderQueueRange.transparent;
        context.DrawRenderers(
            cull.visibleRenderers, ref drawSettings, filterSettings);

        DrawDefaultPipeline(context, camera);

        if (renderToTexture)
        {
            if (activeStack)
            {
                activeStack.RenderAfterTransparent(postProcessingBuffer, cameraColorTextureID, cameraDepthTextureID
                                                   , renderWidth, renderHeight, renderSamples, format);
                context.ExecuteCommandBuffer(postProcessingBuffer);
                postProcessingBuffer.Clear();
            }
            else
            {
                cameraBuffer.Blit(cameraColorTextureID, BuiltinRenderTextureType.CameraTarget);
            }


            cameraBuffer.ReleaseTemporaryRT(cameraColorTextureID);
            if (needsDepth)
            {
                cameraBuffer.ReleaseTemporaryRT(cameraDepthTextureID);
            }
        }

        cameraBuffer.EndSample("Render Camera");
        context.ExecuteCommandBuffer(cameraBuffer);
        cameraBuffer.Clear();

        context.Submit();

        if (shadowMap)
        {
            RenderTexture.ReleaseTemporary(shadowMap);
            shadowMap = null;
        }

        if (cascadedShadowMap)
        {
            RenderTexture.ReleaseTemporary(cascadedShadowMap);
            cascadedShadowMap = null;
        }
    }
Example #7
0
    void Render(ScriptableRenderContext context, Camera camera)
    {
        ScriptableCullingParameters cullingParameters;

        if (!CullResults.GetCullingParameters(camera, out cullingParameters))
        {
            return;
        }
        cullingParameters.shadowDistance =
            Mathf.Min(shadowDistance, camera.farClipPlane);
#if UNITY_EDITOR
        if (camera.cameraType == CameraType.SceneView)
        {
            ScriptableRenderContext.EmitWorldGeometryForSceneView(camera);
        }
#endif
        CullResults.Cull(ref cullingParameters, context, ref cull);
        if (cull.visibleLights.Count > 0)
        {
            ConfigureLights();
            if (mainLightExists)
            {
                RenderCascadedShadows(context);
            }
            else
            {
                cameraBuffer.DisableShaderKeyword(cascadedShadowsHardKeyword);
                cameraBuffer.DisableShaderKeyword(cascadedShadowsSoftKeyword);
            }
            if (shadowTileCount > 0)
            {
                RenderShadows(context);
            }
            else
            {
                cameraBuffer.DisableShaderKeyword(shadowsHardKeyword);
                cameraBuffer.DisableShaderKeyword(shadowsSoftKeyword);
            }
        }
        else
        {
            cameraBuffer.SetGlobalVector(
                lightIndecesOffsetAndCountId, Vector4.zero
                );
            cameraBuffer.DisableShaderKeyword(cascadedShadowsHardKeyword);
            cameraBuffer.DisableShaderKeyword(cascadedShadowsSoftKeyword);
            cameraBuffer.DisableShaderKeyword(shadowsHardKeyword);
            cameraBuffer.DisableShaderKeyword(shadowsSoftKeyword);
        }
        ConfigureLights();

        context.SetupCameraProperties(camera);

        var myPipelineCamera = camera.GetComponent <MyPipelineCamera>();
        MyPostProcessingStack activeStack = myPipelineCamera ?
                                            myPipelineCamera.PostProcessingStack : defaultStack;

        bool scaledRendering =
            (renderScale <1f || renderScale> 1f) && camera.cameraType == CameraType.Game;

        int renderWidth  = camera.pixelWidth;
        int renderHeight = camera.pixelHeight;
        if (scaledRendering)
        {
            renderWidth  = (int)(renderWidth * renderScale);
            renderHeight = (int)(renderHeight * renderScale);
        }
        int  renderSamples      = camera.allowMSAA ? msaaSamples : 1;
        bool renderToTexture    = scaledRendering || renderSamples > 1 || activeStack;
        bool needsDepth         = activeStack && activeStack.NeedsDepth;
        bool needsDirectDepth   = needsDepth && renderSamples == 1;
        bool needsDepthOnlyPass = needsDepth && renderSamples > 1;

        RenderTextureFormat format = allowHDR && camera.allowHDR ?
                                     RenderTextureFormat.DefaultHDR : RenderTextureFormat.Default;
        if (renderToTexture)
        {
            cameraBuffer.GetTemporaryRT(
                cameraColorTextureId, renderWidth, renderHeight,
                needsDirectDepth ? 0 : 24,
                FilterMode.Bilinear, format,
                RenderTextureReadWrite.Default, renderSamples
                );
            if (needsDepth)
            {
                cameraBuffer.GetTemporaryRT(
                    cameraDepthTextureId, renderWidth, renderHeight, 24,
                    FilterMode.Point, RenderTextureFormat.Depth,
                    RenderTextureReadWrite.Linear, 1
                    );
            }
            if (needsDirectDepth)
            {
                cameraBuffer.SetRenderTarget(
                    cameraColorTextureId,
                    RenderBufferLoadAction.DontCare, RenderBufferStoreAction.Store,
                    cameraDepthTextureId,
                    RenderBufferLoadAction.DontCare, RenderBufferStoreAction.Store
                    );
            }
            else
            {
                cameraBuffer.SetRenderTarget(
                    cameraColorTextureId,
                    RenderBufferLoadAction.DontCare, RenderBufferStoreAction.Store
                    );
            }
        }

        CameraClearFlags clearFlags = camera.clearFlags;
        cameraBuffer.ClearRenderTarget(
            (clearFlags & CameraClearFlags.Depth) != 0,
            (clearFlags & CameraClearFlags.Color) != 0,
            camera.backgroundColor
            );

        cameraBuffer.BeginSample("Render Camera");
        cameraBuffer.SetGlobalVectorArray(
            visibleLightColorsId, visibleLightColors
            );
        cameraBuffer.SetGlobalVectorArray(
            visibleLightDirectionsOrPositionsId, visibleLightDirectionsOrPositions
            );
        cameraBuffer.SetGlobalVectorArray(
            visibleLightAttenuationId, visibleLightAttenuations
            );
        cameraBuffer.SetGlobalVectorArray(
            visibleLightSpotDirectionsId, visibleLightSpotDirections
            );
        cameraBuffer.SetGlobalVectorArray(
            visibleLightOcclusionMasksId, visibleLightOcclusionMasks
            );
        globalShadowData.z = 1f - cullingParameters.shadowDistance * globalShadowData.y;
        cameraBuffer.SetGlobalVector(globalShadowDataId, globalShadowData);
        context.ExecuteCommandBuffer(cameraBuffer);
        cameraBuffer.Clear();

        var drawSettings = new DrawRendererSettings(
            camera, new ShaderPassName("SRPDefaultUnlit")
            )
        {
            flags = drawFlags
        };
        if (cull.visibleLights.Count > 0)
        {
            drawSettings.rendererConfiguration =
                RendererConfiguration.PerObjectLightIndices8;
        }
        drawSettings.rendererConfiguration |=
            RendererConfiguration.PerObjectReflectionProbes |
            RendererConfiguration.PerObjectLightmaps |
            RendererConfiguration.PerObjectLightProbe |
            RendererConfiguration.PerObjectLightProbeProxyVolume |
            RendererConfiguration.PerObjectShadowMask |
            RendererConfiguration.PerObjectOcclusionProbe |
            RendererConfiguration.PerObjectOcclusionProbeProxyVolume;

        drawSettings.sorting.flags = SortFlags.CommonOpaque;
        var filterSettings = new FilterRenderersSettings(true)
        {
            renderQueueRange = RenderQueueRange.opaque
        };
        context.DrawRenderers(
            cull.visibleRenderers, ref drawSettings, filterSettings
            );

        context.DrawSkybox(camera);

        if (activeStack)
        {
            if (needsDepthOnlyPass)
            {
                var depthOnlyDrawSettings = new DrawRendererSettings(
                    camera, new ShaderPassName("DepthOnly")
                    )
                {
                    flags = drawFlags
                };
                depthOnlyDrawSettings.sorting.flags = SortFlags.CommonOpaque;
                cameraBuffer.SetRenderTarget(
                    cameraDepthTextureId,
                    RenderBufferLoadAction.DontCare, RenderBufferStoreAction.Store
                    );
                cameraBuffer.ClearRenderTarget(true, false, Color.clear);
                context.ExecuteCommandBuffer(cameraBuffer);
                cameraBuffer.Clear();
                context.DrawRenderers(
                    cull.visibleRenderers, ref depthOnlyDrawSettings, filterSettings
                    );
            }
            activeStack.RenderAfterOpaque(
                postProcessingBuffer, cameraColorTextureId, cameraDepthTextureId,
                renderWidth, renderHeight, msaaSamples, format
                );
            context.ExecuteCommandBuffer(postProcessingBuffer);
            postProcessingBuffer.Clear();

            if (needsDirectDepth)
            {
                cameraBuffer.SetRenderTarget(
                    cameraColorTextureId,
                    RenderBufferLoadAction.Load, RenderBufferStoreAction.Store,
                    cameraDepthTextureId,
                    RenderBufferLoadAction.Load, RenderBufferStoreAction.Store
                    );
            }
            else
            {
                cameraBuffer.SetRenderTarget(
                    cameraColorTextureId,
                    RenderBufferLoadAction.Load, RenderBufferStoreAction.Store
                    );
            }

            context.ExecuteCommandBuffer(cameraBuffer);
            cameraBuffer.Clear();
        }

        drawSettings.sorting.flags      = SortFlags.CommonTransparent;
        filterSettings.renderQueueRange = RenderQueueRange.transparent;
        context.DrawRenderers(
            cull.visibleRenderers, ref drawSettings, filterSettings
            );

        DrawDefaultPipeline(context, camera);

        if (renderToTexture)
        {
            if (activeStack)
            {
                activeStack.RenderAfterTransparent(
                    postProcessingBuffer, cameraColorTextureId, cameraDepthTextureId,
                    renderWidth, renderHeight, msaaSamples, format
                    );
                context.ExecuteCommandBuffer(postProcessingBuffer);
                postProcessingBuffer.Clear();
            }
            else
            {
                cameraBuffer.Blit(
                    cameraColorTextureId, BuiltinRenderTextureType.CameraTarget
                    );
            }

            cameraBuffer.ReleaseTemporaryRT(cameraColorTextureId);
            if (needsDepth)
            {
                cameraBuffer.ReleaseTemporaryRT(cameraDepthTextureId);
            }
        }

        cameraBuffer.EndSample("Render Camera");
        context.ExecuteCommandBuffer(cameraBuffer);
        cameraBuffer.Clear();

        context.Submit();
        if (shadowMap)
        {
            RenderTexture.ReleaseTemporary(shadowMap);
            shadowMap = null;
        }
        if (cascadedShadowMap)
        {
            RenderTexture.ReleaseTemporary(cascadedShadowMap);
            cascadedShadowMap = null;
        }
    }
Example #8
0
    void Render(ScriptableRenderContext context, Camera camera)
    {
        // 剔除参数
        ScriptableCullingParameters cullingParameters;

        // 获取剔除参数
        if (!CullResults.GetCullingParameters(camera, out cullingParameters))
        {
            // 如果相机设定非法,直接返回
            return;
        }

        // 设置阴影参数
        cullingParameters.shadowDistance = Mathf.Min(shadowDistance, camera.farClipPlane);

        // 仅在编辑模式下
#if UNITY_EDITOR
        // 仅在渲染场景视图时。否则游戏视图中的UI元素会被渲染两次
        if (camera.cameraType == CameraType.SceneView)
        {
            // 当canvas的渲染被设置在世界空间时,UI元素不会出现在场景视图中
            // 需要手动指定以使其正确显示
            ScriptableRenderContext.EmitWorldGeometryForSceneView(camera);
        }
#endif

        // 剔除
        CullResults.Cull(ref cullingParameters, context, ref cull);

        if (cull.visibleLights.Count > 0)
        {
            ConfigureLights();

            if (mainLightExists)
            {
                RenderCascadedShadows(context);
            }
            else
            {
                cameraBuffer.DisableShaderKeyword(cascadedShadowsHardKeyword);
                cameraBuffer.DisableShaderKeyword(cascadedShadowsSoftKeyword);
            }

            if (shadowTileCount > 0)
            {
                RenderShadows(context);
            }
            else
            {
                cameraBuffer.DisableShaderKeyword(shadowsHardKeyword);
                cameraBuffer.DisableShaderKeyword(shadowsSoftKeyword);
            }
        }
        else
        {
            // 由于该值会被保留为上一个物体使用的值,因此需要手动设置
            cameraBuffer.SetGlobalVector(lightIndicesOffsetAndCountID, Vector4.zero);

            cameraBuffer.DisableShaderKeyword(cascadedShadowsHardKeyword);
            cameraBuffer.DisableShaderKeyword(cascadedShadowsSoftKeyword);
            cameraBuffer.DisableShaderKeyword(shadowsHardKeyword);
            cameraBuffer.DisableShaderKeyword(shadowsSoftKeyword);
        }

        // 设置unity_MatrixVP,以及一些其他属性
        context.SetupCameraProperties(camera);

        // 获取摄像机的定制后处理栈
        var myPipelineCamera = camera.GetComponent <MyPipelineCamera>();
        MyPostProcessingStack activeStack = myPipelineCamera ? myPipelineCamera.PostProcessingStack : defaultStack;

        // 只影响游戏摄像机
        bool scaledRendering = (renderScale <1f || renderScale> 1f) && camera.cameraType == CameraType.Game;

        int renderWidth  = camera.pixelWidth;
        int renderHeight = camera.pixelHeight;
        if (scaledRendering)
        {
            renderWidth  = (int)(renderWidth * renderScale);
            renderHeight = (int)(renderHeight * renderScale);
        }

        // 摄像机是否开启MSAA
        int renderSamples = camera.allowMSAA ? msaaSamples : 1;

        // 开启渲染到纹理
        bool renderToTexture = scaledRendering || renderSamples > 1 || activeStack;

        // 是否需要深度纹理(深度纹理不支持MSAA)
        bool needsDepth         = activeStack && activeStack.NeedsDepth;
        bool needsDirectDepth   = needsDepth && renderSamples == 1;       // 不使用MSAA
        bool needsDepthOnlyPass = needsDepth && renderSamples > 1;        // 使用MSAA、

        // 纹理格式
        RenderTextureFormat format = allowHDR && camera.allowHDR ? RenderTextureFormat.DefaultHDR : RenderTextureFormat.Default;

        // 获取并设置渲染目标,用于后处理
        if (renderToTexture)
        {
            cameraBuffer.GetTemporaryRT(
                cameraColorTextureId, renderWidth, renderHeight, needsDirectDepth ? 0 : 24,
                FilterMode.Bilinear, format,
                RenderTextureReadWrite.Default, renderSamples
                );
            if (needsDepth)
            {
                cameraBuffer.GetTemporaryRT(
                    cameraDepthTextureId, renderWidth, renderHeight, 24,
                    FilterMode.Point, RenderTextureFormat.Depth,
                    RenderTextureReadWrite.Linear, 1                     // 1表示不使用MSAA
                    );
            }
            if (needsDirectDepth)
            {
                cameraBuffer.SetRenderTarget(
                    cameraColorTextureId,
                    RenderBufferLoadAction.DontCare, RenderBufferStoreAction.Store,
                    cameraDepthTextureId,
                    RenderBufferLoadAction.DontCare, RenderBufferStoreAction.Store
                    );
            }
            else
            {
                cameraBuffer.SetRenderTarget(
                    cameraColorTextureId,
                    RenderBufferLoadAction.DontCare, RenderBufferStoreAction.Store
                    );
            }
        }

        // 清空
        CameraClearFlags clearFlags = camera.clearFlags;
        cameraBuffer.ClearRenderTarget((clearFlags & CameraClearFlags.Depth) != 0, (clearFlags & CameraClearFlags.Color) != 0, camera.backgroundColor);

        // 设置采样标志,用于在Frame Debugger中组织结构
        cameraBuffer.BeginSample("HY Render Camera");

        // 设置光数据
        cameraBuffer.SetGlobalVectorArray(visibleLightColorsId, visibleLightColors);
        cameraBuffer.SetGlobalVectorArray(visibleLightDirectionsOrPositionsId, visibleLightDirectionsOrPositions);
        cameraBuffer.SetGlobalVectorArray(visibleLightAttenuationsId, visibleLightAttenuations);
        cameraBuffer.SetGlobalVectorArray(visibleLightSpotDirectionsId, visibleLightSpotDirections);

        // 执行指令缓冲。这并不会立即执行指令,只是将指令拷贝到上下文的内部缓冲中
        context.ExecuteCommandBuffer(cameraBuffer);
        cameraBuffer.Clear();

        // 绘制设定
        // camera参数设定排序和剔除层,pass参数指定使用哪一个shader pass
        var drawSettings = new DrawRendererSettings(camera, new ShaderPassName("SRPDefaultUnlit"))
        {
            flags = drawFlags
        };
        // 仅在有可见光时设置,否则Unity会崩溃
        if (cull.visibleLights.Count > 0)
        {
            // 指定Unity为每个物体传输光索引数据
            drawSettings.rendererConfiguration = RendererConfiguration.PerObjectLightIndices8;
        }
        // 指定使用反射探针,如果场景中没有反射探针,则使用天空球的立方体贴图
        drawSettings.rendererConfiguration |= RendererConfiguration.PerObjectReflectionProbes | RendererConfiguration.PerObjectLightmaps;
        // 指定排序,从前往后
        drawSettings.sorting.flags = SortFlags.CommonOpaque;

        // 过滤设定
        // true表示包括所有物体
        var filterSettings = new FilterRenderersSettings(true)
        {
            // 绘制不透明物体,渲染队列为[0,2500]
            renderQueueRange = RenderQueueRange.opaque
        };

        context.DrawRenderers(cull.visibleRenderers, ref drawSettings, filterSettings);

        // 绘制天空盒
        // camera参数仅用来判断是否绘制天空盒(根据camera的清空标志位)
        context.DrawSkybox(camera);

        // 后处理
        if (activeStack)
        {
            // depth-only pass
            if (needsDepthOnlyPass)
            {
                var depthOnlyDrawSettings = new DrawRendererSettings(
                    camera, new ShaderPassName("DepthOnly")
                    )
                {
                    flags = drawFlags
                };
                depthOnlyDrawSettings.sorting.flags = SortFlags.CommonOpaque;
                cameraBuffer.SetRenderTarget(
                    cameraDepthTextureId,
                    RenderBufferLoadAction.DontCare, RenderBufferStoreAction.Store
                    );
                cameraBuffer.ClearRenderTarget(true, false, Color.clear);
                context.ExecuteCommandBuffer(cameraBuffer);
                cameraBuffer.Clear();
                context.DrawRenderers(
                    cull.visibleRenderers, ref depthOnlyDrawSettings, filterSettings
                    );
            }

            activeStack.RenderAfterOpaque(
                postProcessingBuffer, cameraColorTextureId, cameraDepthTextureId,
                renderWidth, renderHeight, renderSamples, format
                );
            context.ExecuteCommandBuffer(postProcessingBuffer);
            postProcessingBuffer.Clear();

            if (needsDirectDepth)
            {
                cameraBuffer.SetRenderTarget(
                    cameraColorTextureId,
                    RenderBufferLoadAction.Load, RenderBufferStoreAction.Store,
                    cameraDepthTextureId,
                    RenderBufferLoadAction.Load, RenderBufferStoreAction.Store
                    );
            }
            else
            {
                cameraBuffer.SetRenderTarget(
                    cameraColorTextureId,
                    RenderBufferLoadAction.Load, RenderBufferStoreAction.Store
                    );
            }
            context.ExecuteCommandBuffer(cameraBuffer);
            cameraBuffer.Clear();
        }

        // 指定排序,从后往前
        drawSettings.sorting.flags = SortFlags.CommonTransparent;
        // 绘制透明物体,渲染队列为[2501,5000]
        filterSettings.renderQueueRange = RenderQueueRange.transparent;
        context.DrawRenderers(cull.visibleRenderers, ref drawSettings, filterSettings);

        DrawDefaultPipeline(context, camera);

        // 后处理
        if (renderToTexture)
        {
            if (activeStack)
            {
                activeStack.RenderAfterTransparent(
                    postProcessingBuffer, cameraColorTextureId,
                    cameraDepthTextureId, renderWidth, renderHeight, renderSamples, format
                    );
                context.ExecuteCommandBuffer(postProcessingBuffer);
                postProcessingBuffer.Clear();
            }
            else
            {
                cameraBuffer.Blit(
                    cameraColorTextureId, BuiltinRenderTextureType.CameraTarget
                    );
            }
            cameraBuffer.ReleaseTemporaryRT(cameraColorTextureId);
            if (needsDepth)
            {
                cameraBuffer.ReleaseTemporaryRT(cameraDepthTextureId);
            }
        }

        cameraBuffer.EndSample("HY Render Camera");
        context.ExecuteCommandBuffer(cameraBuffer);
        cameraBuffer.Clear();

        // 提交指令
        context.Submit();

        // 释放阴影纹理
        if (shadowMap)
        {
            RenderTexture.ReleaseTemporary(shadowMap);
            shadowMap = null;
        }

        // 释放层级阴影纹理
        if (cascadedShadowMap)
        {
            RenderTexture.ReleaseTemporary(cascadedShadowMap);
            cascadedShadowMap = null;
        }
    }