Esempio n. 1
0
    protected override void Render(ScriptableRenderContext context, Camera[] cameras)
    {
        BeginFrameRendering(context, cameras);

        foreach (Camera camera in cameras)
        {
            BeginCameraRendering(context, camera);

            //Culling
            ScriptableCullingParameters cullingParams;
            if (!camera.TryGetCullingParameters(out cullingParams))
            {
                continue;
            }
            CullingResults cull = context.Cull(ref cullingParams);

            //Camera setup some builtin variables e.g. camera projection matrices etc
            context.SetupCameraProperties(camera);

            //Get the setting from camera component
            bool drawSkyBox = camera.clearFlags == CameraClearFlags.Skybox? true : false;
            bool clearDepth = camera.clearFlags == CameraClearFlags.Nothing? false : true;
            bool clearColor = camera.clearFlags == CameraClearFlags.Color? true : false;

            //************************** Set TempRT ************************************

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

            //Color
            m_ColorFormatActive = camera.allowHDR ? m_ColorFormatHDR : m_ColorFormat;
            RenderTextureDescriptor colorRTDesc = new RenderTextureDescriptor(camera.pixelWidth, camera.pixelHeight);
            colorRTDesc.graphicsFormat    = m_ColorFormatActive;
            colorRTDesc.depthBufferBits   = depthBufferBits;
            colorRTDesc.sRGB              = (QualitySettings.activeColorSpace == ColorSpace.Linear);
            colorRTDesc.msaaSamples       = camera.allowMSAA ? QualitySettings.antiAliasing : 1;
            colorRTDesc.enableRandomWrite = false;
            cmdTempId.GetTemporaryRT(m_ColorRTid, colorRTDesc, FilterMode.Bilinear);

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

            //************************** Setup DrawSettings and FilterSettings ************************************

            var               sortingSettings   = new SortingSettings(camera);
            DrawingSettings   drawSettings      = new DrawingSettings(m_PassName, sortingSettings);
            FilteringSettings filterSettings    = new FilteringSettings(RenderQueueRange.all);
            DrawingSettings   drawSettingsDepth = new DrawingSettings(m_PassName, sortingSettings)
            {
                perObjectData             = PerObjectData.None,
                overrideMaterial          = depthOnlyMaterial,
                overrideMaterialPassIndex = 0
            };

            //************************** Rendering depth ************************************

            //Set RenderTarget & Camera clear flag
            CommandBuffer cmdDepth = new CommandBuffer();
            cmdDepth.name = "(" + camera.name + ")" + "Depth Clear Flag";
            cmdDepth.SetRenderTarget(m_DepthRT); //Set CameraTarget to the depth texture

            cmdDepth.ClearRenderTarget(true, true, Color.black);
            //MyDebug(camera,context,m_DepthRT,colorRTDesc,null);
            context.ExecuteCommandBuffer(cmdDepth);
            //MyDebug(camera,context,m_DepthRT,colorRTDesc,null);
            cmdDepth.Release();

            //Opaque objects
            sortingSettings.criteria          = SortingCriteria.CommonOpaque;
            drawSettingsDepth.sortingSettings = sortingSettings;
            filterSettings.renderQueueRange   = RenderQueueRange.opaque;
            context.DrawRenderers(cull, ref drawSettingsDepth, ref filterSettings);

            //To let shader has _CameraDepthTexture, to make Depth of Field work
            CommandBuffer cmdDepthTexture = new CommandBuffer();
            cmdDepthTexture.name = "(" + camera.name + ")" + "Depth Texture";
            cmdDepthTexture.SetGlobalTexture(m_DepthRTid, m_DepthRT);
            context.ExecuteCommandBuffer(cmdDepthTexture);
            //MyDebug(camera,context,m_DepthRT,colorRTDesc,null);
            cmdDepthTexture.Release();

            //************************** Rendering colors ************************************

            //Set RenderTarget & Camera clear flag
            CommandBuffer cmd = new CommandBuffer();
            cmd.name = "(" + camera.name + ")" + "Clear Flag";
            cmd.SetRenderTarget(m_ColorRT); //Set CameraTarget to the color texture
            cmd.ClearRenderTarget(clearDepth, clearColor, camera.backgroundColor);
            context.ExecuteCommandBuffer(cmd);
            //MyDebug(camera,context,m_ColorRT,colorRTDesc,null);
            cmd.Release();

            //Skybox
            if (drawSkyBox)
            {
                context.DrawSkybox(camera);
            }

            AfterSkybox(camera, context);
            //************************** Rendering Opaque Objects ************************************

            sortingSettings.criteria        = SortingCriteria.CommonOpaque;
            drawSettings.sortingSettings    = sortingSettings;
            filterSettings.renderQueueRange = RenderQueueRange.opaque;
            context.DrawRenderers(cull, ref drawSettings, ref filterSettings);
            AfterOpaqueObject(camera, context);
            //************************** SetUp Post-processing ************************************

            PostProcessLayer         m_CameraPostProcessLayer   = camera.GetComponent <PostProcessLayer>();
            bool                     hasPostProcessing          = m_CameraPostProcessLayer != null;
            bool                     usePostProcessing          = false;
            bool                     hasOpaqueOnlyEffects       = false;
            PostProcessRenderContext m_PostProcessRenderContext = null;
            if (hasPostProcessing)
            {
                m_PostProcessRenderContext = new PostProcessRenderContext();
                usePostProcessing          = m_CameraPostProcessLayer.enabled;
                hasOpaqueOnlyEffects       = m_CameraPostProcessLayer.HasOpaqueOnlyEffects(m_PostProcessRenderContext);
            }

            //************************** Opaque Post-processing ************************************
            //Ambient Occlusion, Screen-spaced reflection are generally not supported for SRP
            //So this part is only for custom opaque post-processing
            if (usePostProcessing)
            {
                CommandBuffer cmdpp = new CommandBuffer();
                cmdpp.name = "(" + camera.name + ")" + "Post-processing Opaque";

                m_PostProcessRenderContext.Reset();
                m_PostProcessRenderContext.camera       = camera;
                m_PostProcessRenderContext.source       = m_ColorRT;
                m_PostProcessRenderContext.sourceFormat = UnityEngine.Experimental.Rendering.GraphicsFormatUtility.GetRenderTextureFormat(m_ColorFormatActive);
                m_PostProcessRenderContext.destination  = m_ColorRT;
                m_PostProcessRenderContext.command      = cmdpp;
                m_PostProcessRenderContext.flip         = camera.targetTexture == null;//是否反转画面
                m_CameraPostProcessLayer.RenderOpaqueOnly(m_PostProcessRenderContext);

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

            //************************** Rendering Transparent Objects ************************************

            sortingSettings.criteria        = SortingCriteria.CommonTransparent;
            drawSettings.sortingSettings    = sortingSettings;
            filterSettings.renderQueueRange = RenderQueueRange.transparent;
            context.DrawRenderers(cull, ref drawSettings, ref filterSettings);
            AfterTransparentObject(camera, context, m_DepthRTid, depthRTDesc);
            //************************** Transparent Post-processing ************************************
            //Bloom, Vignette, Grain, ColorGrading, LensDistortion, Chromatic Aberration, Auto Exposure
            if (usePostProcessing)
            {
                CommandBuffer cmdpp = new CommandBuffer();
                cmdpp.name = "(" + camera.name + ")" + "Post-processing Transparent";

                m_PostProcessRenderContext.Reset();
                m_PostProcessRenderContext.camera       = camera;
                m_PostProcessRenderContext.source       = m_ColorRT;
                m_PostProcessRenderContext.sourceFormat = UnityEngine.Experimental.Rendering.GraphicsFormatUtility.GetRenderTextureFormat(m_ColorFormatActive);
                m_PostProcessRenderContext.destination  = BuiltinRenderTextureType.CameraTarget;
                m_PostProcessRenderContext.command      = cmdpp;
                m_PostProcessRenderContext.flip         = camera.targetTexture == null;
                m_CameraPostProcessLayer.Render(m_PostProcessRenderContext);

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

            //************************** Make sure screen has the thing when Postprocessing is off ************************************
            if (!usePostProcessing)
            {
                CommandBuffer cmdBlitToCam = new CommandBuffer();
                cmdBlitToCam.name = "(" + camera.name + ")" + "Blit back to Camera";
                cmdBlitToCam.Blit(m_ColorRTid, BuiltinRenderTextureType.CameraTarget);
                //MDebug.MyDebug();
                context.ExecuteCommandBuffer(cmdBlitToCam);
                cmdBlitToCam.Release();
            }

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

            context.Submit();

            EndCameraRendering(context, camera);
        }

        EndFrameRendering(context, cameras);
    }
        public FrameRenderingConfiguration SetupFrameRenderingConfiguration(CameraContext cameraContext, ShadowManager shadowManager)
        {
            var configuration = (cameraContext.StereoEnabled) ? FrameRenderingConfiguration.Stereo : FrameRenderingConfiguration.None;

            if (cameraContext.StereoEnabled && XRSettings.eyeTextureDesc.dimension == TextureDimension.Tex2DArray)
            {
                m_IntermediateTextureArray = true;
            }
            else
            {
                m_IntermediateTextureArray = false;
            }

            var  camera              = cameraContext.Camera;
            bool hdrEnabled          = m_Asset.SupportsHDR && camera.allowHDR;
            bool intermediateTexture = camera.targetTexture != null || camera.cameraType == CameraType.SceneView ||
                                       m_Asset.RenderScale < 1.0f || hdrEnabled;

            m_ColorFormat            = hdrEnabled ? RenderTextureFormat.DefaultHDR : RenderTextureFormat.Default;
            m_RequireCopyColor       = false;
            m_DepthRenderBuffer      = false;
            m_CameraPostProcessLayer = camera.GetComponent <PostProcessLayer>();

            bool msaaEnabled = camera.allowMSAA && m_Asset.MSAASampleCount > 1 && (camera.targetTexture == null || camera.targetTexture.antiAliasing > 1);

            // TODO: PostProcessing and SoftParticles are currently not support for VR
            bool postProcessEnabled = m_CameraPostProcessLayer != null && m_CameraPostProcessLayer.enabled && !cameraContext.StereoEnabled;

            m_RequireDepthTexture = m_Asset.RequireDepthTexture && !cameraContext.StereoEnabled;
            if (postProcessEnabled)
            {
                m_RequireDepthTexture = true;
                intermediateTexture   = true;

                configuration |= FrameRenderingConfiguration.PostProcess;
                if (m_CameraPostProcessLayer.HasOpaqueOnlyEffects(m_PostProcessRenderContext))
                {
                    configuration |= FrameRenderingConfiguration.BeforeTransparentPostProcess;
                    if (m_CameraPostProcessLayer.sortedBundles[PostProcessEvent.BeforeTransparent].Count == 1)
                    {
                        m_RequireCopyColor = true;
                    }
                }
            }

            if (cameraContext.SceneViewCamera)
            {
                m_RequireDepthTexture = true;
            }

            if (shadowManager.Shadows)
            {
                m_RequireDepthTexture = shadowManager.IsScreenSpace;

                if (!msaaEnabled)
                {
                    intermediateTexture = true;
                }
            }

            if (msaaEnabled)
            {
                configuration      |= FrameRenderingConfiguration.Msaa;
                intermediateTexture = intermediateTexture || !LightweightUtils.PlatformSupportsMSAABackBuffer();
            }

            if (m_RequireDepthTexture)
            {
                // If msaa is enabled we don't use a depth renderbuffer as we might not have support to Texture2DMS to resolve depth.
                // Instead we use a depth prepass and whenever depth is needed we use the 1 sample depth from prepass.
                // Screen space shadows require depth before opaque shading.
                if (!msaaEnabled && !shadowManager.Shadows)
                {
                    bool supportsDepthCopy = m_CopyTextureSupport != CopyTextureSupport.None && m_Asset.CopyDepthShader.isSupported;
                    m_DepthRenderBuffer = true;
                    intermediateTexture = true;

                    // If requiring a camera depth texture we need separate depth as it reads/write to depth at same time
                    // Post process doesn't need the copy
                    if (!m_Asset.RequireDepthTexture && postProcessEnabled)
                    {
                        configuration |= (supportsDepthCopy) ? FrameRenderingConfiguration.DepthCopy : FrameRenderingConfiguration.DepthPrePass;
                    }
                }
                else
                {
                    configuration |= FrameRenderingConfiguration.DepthPrePass;
                }
            }

            Rect cameraRect = camera.rect;

            if (!(Math.Abs(cameraRect.x) > 0.0f || Math.Abs(cameraRect.y) > 0.0f || Math.Abs(cameraRect.width) < 1.0f || Math.Abs(cameraRect.height) < 1.0f))
            {
                configuration |= FrameRenderingConfiguration.DefaultViewport;
            }
            else
            {
                intermediateTexture = true;
            }

            if (intermediateTexture)
            {
                configuration |= FrameRenderingConfiguration.IntermediateTexture;
            }

            return(configuration);
        }