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); }