/// <inheritdoc/> public override void Execute(ScriptableRenderer renderer, ScriptableRenderContext context, ref RenderingData renderingData) { if (m_CopyDepthMaterial == null) { Debug.LogErrorFormat("Missing {0}. {1} render pass will not execute. Check for missing reference in the renderer resources.", m_CopyDepthMaterial, GetType().Name); return; } if (renderer == null) { throw new ArgumentNullException("renderer"); } CommandBuffer cmd = CommandBufferPool.Get(k_DepthCopyTag); RenderTargetIdentifier depthSurface = source.Identifier(); RenderTargetIdentifier copyDepthSurface = destination.Identifier(); RenderTextureDescriptor descriptor = ScriptableRenderer.CreateRenderTextureDescriptor(ref renderingData.cameraData); descriptor.colorFormat = RenderTextureFormat.Depth; descriptor.depthBufferBits = 32; //TODO: fix this ; descriptor.msaaSamples = 1; descriptor.bindMS = false; cmd.GetTemporaryRT(destination.id, descriptor, FilterMode.Point); cmd.SetGlobalTexture("_CameraDepthAttachment", source.Identifier()); if (renderingData.cameraData.msaaSamples > 1) { cmd.DisableShaderKeyword(ShaderKeywordStrings.DepthNoMsaa); if (renderingData.cameraData.msaaSamples == 4) { cmd.DisableShaderKeyword(ShaderKeywordStrings.DepthMsaa2); cmd.EnableShaderKeyword(ShaderKeywordStrings.DepthMsaa4); } else { cmd.EnableShaderKeyword(ShaderKeywordStrings.DepthMsaa2); cmd.DisableShaderKeyword(ShaderKeywordStrings.DepthMsaa4); } cmd.Blit(depthSurface, copyDepthSurface, m_CopyDepthMaterial); } else { cmd.EnableShaderKeyword(ShaderKeywordStrings.DepthNoMsaa); cmd.DisableShaderKeyword(ShaderKeywordStrings.DepthMsaa2); cmd.DisableShaderKeyword(ShaderKeywordStrings.DepthMsaa4); ScriptableRenderer.CopyTexture(cmd, depthSurface, copyDepthSurface, m_CopyDepthMaterial); } context.ExecuteCommandBuffer(cmd); CommandBufferPool.Release(cmd); }
/// <inheritdoc/> public override void Execute(ScriptableRenderer renderer, ScriptableRenderContext context, ref RenderingData renderingData) { if (m_SamplingMaterial == null) { Debug.LogErrorFormat("Missing {0}. {1} render pass will not execute. Check for missing reference in the renderer resources.", m_SamplingMaterial, GetType().Name); return; } if (renderer == null) { throw new ArgumentNullException("renderer"); } CommandBuffer cmd = CommandBufferPool.Get(k_CopyColorTag); Downsampling downsampling = renderingData.cameraData.opaqueTextureDownsampling; float opaqueScaler = m_OpaqueScalerValues[(int)downsampling]; RenderTextureDescriptor opaqueDesc = ScriptableRenderer.CreateRenderTextureDescriptor(ref renderingData.cameraData, opaqueScaler); opaqueDesc.msaaSamples = 1; opaqueDesc.depthBufferBits = 0; RenderTargetIdentifier colorRT = source.Identifier(); RenderTargetIdentifier opaqueColorRT = destination.Identifier(); cmd.GetTemporaryRT(destination.id, opaqueDesc, renderingData.cameraData.opaqueTextureDownsampling == Downsampling.None ? FilterMode.Point : FilterMode.Bilinear); switch (downsampling) { case Downsampling.None: cmd.Blit(colorRT, opaqueColorRT); break; case Downsampling._2xBilinear: cmd.Blit(colorRT, opaqueColorRT); break; case Downsampling._4xBox: m_SamplingMaterial.SetFloat(m_SampleOffsetShaderHandle, 2); cmd.Blit(colorRT, opaqueColorRT, m_SamplingMaterial, 0); break; case Downsampling._4xBilinear: cmd.Blit(colorRT, opaqueColorRT); break; } context.ExecuteCommandBuffer(cmd); CommandBufferPool.Release(cmd); }
/// <inheritdoc/> public override void Execute(ScriptableRenderer renderer, ScriptableRenderContext context, ref RenderingData renderingData) { if (renderer == null) { throw new ArgumentNullException("renderer"); } CommandBuffer cmd = CommandBufferPool.Get(k_CopyColorTag); Downsampling downsampling = renderingData.cameraData.opaqueTextureDownsampling; float opaqueScaler = m_OpaqueScalerValues[(int)downsampling]; RenderTextureDescriptor opaqueDesc = ScriptableRenderer.CreateRenderTextureDescriptor(ref renderingData.cameraData, opaqueScaler); RenderTargetIdentifier colorRT = source.Identifier(); RenderTargetIdentifier opaqueColorRT = destination.Identifier(); cmd.GetTemporaryRT(destination.id, opaqueDesc, renderingData.cameraData.opaqueTextureDownsampling == Downsampling.None ? FilterMode.Point : FilterMode.Bilinear); switch (downsampling) { case Downsampling.None: cmd.Blit(colorRT, opaqueColorRT); break; case Downsampling._2xBilinear: cmd.Blit(colorRT, opaqueColorRT); break; case Downsampling._4xBox: Material samplingMaterial = renderer.GetMaterial(MaterialHandle.Sampling); samplingMaterial.SetFloat(m_SampleOffsetShaderHandle, 2); cmd.Blit(colorRT, opaqueColorRT, samplingMaterial, 0); break; case Downsampling._4xBilinear: cmd.Blit(colorRT, opaqueColorRT); break; } context.ExecuteCommandBuffer(cmd); CommandBufferPool.Release(cmd); }
public void Setup(ScriptableRenderer renderer, ref RenderingData renderingData) { Init(); Camera camera = renderingData.cameraData.camera; renderer.SetupPerObjectLightIndices(ref renderingData.cullResults, ref renderingData.lightData); RenderTextureDescriptor baseDescriptor = ScriptableRenderer.CreateRenderTextureDescriptor(ref renderingData.cameraData); ClearFlag clearFlag = ScriptableRenderer.GetCameraClearFlag(renderingData.cameraData.camera); RenderTextureDescriptor shadowDescriptor = baseDescriptor; shadowDescriptor.dimension = TextureDimension.Tex2D; bool mainLightShadows = false; if (renderingData.shadowData.supportsMainLightShadows) { mainLightShadows = m_MainLightShadowCasterPass.Setup(m_MainLightShadowmap, ref renderingData); if (mainLightShadows) { renderer.EnqueuePass(m_MainLightShadowCasterPass); } } if (renderingData.shadowData.supportsAdditionalLightShadows) { bool additionalLightShadows = m_AdditionalLightsShadowCasterPass.Setup(m_AdditionalLightsShadowmap, ref renderingData, renderer.maxVisibleAdditionalLights); if (additionalLightShadows) { renderer.EnqueuePass(m_AdditionalLightsShadowCasterPass); } } bool resolveShadowsInScreenSpace = mainLightShadows && renderingData.shadowData.requiresScreenSpaceShadowResolve; // Depth prepass is generated in the following cases: // - We resolve shadows in screen space // - Scene view camera always requires a depth texture. We do a depth pre-pass to simplify it and it shouldn't matter much for editor. // - If game or offscreen camera requires it we check if we can copy the depth from the rendering opaques pass and use that instead. bool requiresDepthPrepass = resolveShadowsInScreenSpace || renderingData.cameraData.isSceneViewCamera || (renderingData.cameraData.requiresDepthTexture && (!CanCopyDepth(ref renderingData.cameraData))); // For now VR requires a depth prepass until we figure out how to properly resolve texture2DMS in stereo requiresDepthPrepass |= renderingData.cameraData.isStereoEnabled; renderer.EnqueuePass(m_SetupForwardRenderingPass); camera.GetComponents(m_BeforeRenderPasses); camera.GetComponents(m_AfterOpaquePasses); camera.GetComponents(m_AfterOpaquePostProcessPasses); camera.GetComponents(m_AfterSkyboxPasses); camera.GetComponents(m_AfterTransparentPasses); camera.GetComponents(m_AfterRenderPasses); bool createColorTexture = RequiresIntermediateColorTexture(ref renderingData, baseDescriptor) || m_BeforeRenderPasses.Count != 0 || m_AfterOpaquePasses.Count != 0 || m_AfterOpaquePostProcessPasses.Count != 0 || m_AfterSkyboxPasses.Count != 0 || m_AfterTransparentPasses.Count != 0 || m_AfterRenderPasses.Count != 0; // If camera requires depth and there's no depth pre-pass we create a depth texture that can be read // later by effect requiring it. bool createDepthTexture = renderingData.cameraData.requiresDepthTexture && !requiresDepthPrepass; RenderTargetHandle colorHandle = (createColorTexture) ? m_ColorAttachment : RenderTargetHandle.CameraTarget; RenderTargetHandle depthHandle = (createDepthTexture) ? m_DepthAttachment : RenderTargetHandle.CameraTarget; var sampleCount = (SampleCount)renderingData.cameraData.msaaSamples; if (createColorTexture || createDepthTexture) { m_CreateLightweightRenderTexturesPass.Setup(baseDescriptor, colorHandle, depthHandle, sampleCount); renderer.EnqueuePass(m_CreateLightweightRenderTexturesPass); } foreach (var pass in m_BeforeRenderPasses) { renderer.EnqueuePass(pass.GetPassToEnqueue(baseDescriptor, colorHandle, depthHandle, clearFlag)); } if (requiresDepthPrepass) { m_DepthOnlyPass.Setup(baseDescriptor, m_DepthTexture); renderer.EnqueuePass(m_DepthOnlyPass); } if (resolveShadowsInScreenSpace) { m_ScreenSpaceShadowResolvePass.Setup(baseDescriptor, m_ScreenSpaceShadowmap); renderer.EnqueuePass(m_ScreenSpaceShadowResolvePass); } if (renderingData.cameraData.isStereoEnabled) { renderer.EnqueuePass(m_BeginXrRenderingPass); } var perObjectFlags = ScriptableRenderer.GetPerObjectLightFlags(renderingData.lightData.mainLightIndex, renderingData.lightData.additionalLightsCount); m_SetupLightweightConstants.Setup(renderer.maxVisibleAdditionalLights, renderer.perObjectLightIndices); renderer.EnqueuePass(m_SetupLightweightConstants); // If a before all render pass executed we expect it to clear the color render target if (m_BeforeRenderPasses.Count != 0) { clearFlag = ClearFlag.None; } m_RenderOpaqueForwardPass.Setup(baseDescriptor, colorHandle, depthHandle, clearFlag, camera.backgroundColor, perObjectFlags); renderer.EnqueuePass(m_RenderOpaqueForwardPass); foreach (var pass in m_AfterOpaquePasses) { renderer.EnqueuePass(pass.GetPassToEnqueue(baseDescriptor, colorHandle, depthHandle)); } if (renderingData.cameraData.postProcessEnabled && renderingData.cameraData.postProcessLayer.HasOpaqueOnlyEffects(renderer.postProcessingContext)) { m_OpaquePostProcessPass.Setup(baseDescriptor, colorHandle, colorHandle, true, false); renderer.EnqueuePass(m_OpaquePostProcessPass); foreach (var pass in m_AfterOpaquePostProcessPasses) { renderer.EnqueuePass(pass.GetPassToEnqueue(baseDescriptor, colorHandle, depthHandle)); } } if (camera.clearFlags == CameraClearFlags.Skybox && RenderSettings.skybox != null) { // We can't combine skybox and render opaques passes if there's a custom render pass in between // them. Ideally we need a render graph here that each render pass declares inputs and output // attachments and their Load/Store action so we figure out properly if we can combine passes // and move to interleaved rendering with RenderPass API. bool combineWithRenderOpaquesPass = m_AfterOpaquePostProcessPasses.Count == 0; m_DrawSkyboxPass.Setup(baseDescriptor, colorHandle, depthHandle, combineWithRenderOpaquesPass); renderer.EnqueuePass(m_DrawSkyboxPass); } foreach (var pass in m_AfterSkyboxPasses) { renderer.EnqueuePass(pass.GetPassToEnqueue(baseDescriptor, colorHandle, depthHandle)); } // If a depth texture was created we necessarily need to copy it, otherwise we could have render it to a renderbuffer if (createDepthTexture) { m_CopyDepthPass.Setup(depthHandle, m_DepthTexture); renderer.EnqueuePass(m_CopyDepthPass); } if (renderingData.cameraData.requiresOpaqueTexture) { m_CopyColorPass.Setup(colorHandle, m_OpaqueColor); renderer.EnqueuePass(m_CopyColorPass); } m_RenderTransparentForwardPass.Setup(baseDescriptor, colorHandle, depthHandle, perObjectFlags); renderer.EnqueuePass(m_RenderTransparentForwardPass); foreach (var pass in m_AfterTransparentPasses) { renderer.EnqueuePass(pass.GetPassToEnqueue(baseDescriptor, colorHandle, depthHandle)); } #if UNITY_EDITOR m_LitGizmoRenderingPass.Setup(true); renderer.EnqueuePass(m_LitGizmoRenderingPass); #endif bool afterRenderExists = m_AfterRenderPasses.Count != 0; // if we have additional filters // we need to stay in a RT if (afterRenderExists) { // perform post with src / dest the same if (renderingData.cameraData.postProcessEnabled) { m_PostProcessPass.Setup(baseDescriptor, colorHandle, colorHandle, false, false); renderer.EnqueuePass(m_PostProcessPass); } //execute after passes foreach (var pass in m_AfterRenderPasses) { renderer.EnqueuePass(pass.GetPassToEnqueue(baseDescriptor, colorHandle, depthHandle)); } //now blit into the final target if (colorHandle != RenderTargetHandle.CameraTarget) { if (m_CapturePass.Setup(colorHandle, renderingData.cameraData.captureActions)) { renderer.EnqueuePass(m_CapturePass); } m_FinalBlitPass.Setup(baseDescriptor, colorHandle, Display.main.requiresSrgbBlitToBackbuffer, renderingData.killAlphaInFinalBlit); renderer.EnqueuePass(m_FinalBlitPass); } } else { if (renderingData.cameraData.postProcessEnabled) { m_PostProcessPass.Setup(baseDescriptor, colorHandle, RenderTargetHandle.CameraTarget, false, renderingData.cameraData.camera.targetTexture == null); renderer.EnqueuePass(m_PostProcessPass); } else if (colorHandle != RenderTargetHandle.CameraTarget) { if (m_CapturePass.Setup(colorHandle, renderingData.cameraData.captureActions)) { renderer.EnqueuePass(m_CapturePass); } m_FinalBlitPass.Setup(baseDescriptor, colorHandle, Display.main.requiresSrgbBlitToBackbuffer, renderingData.killAlphaInFinalBlit); renderer.EnqueuePass(m_FinalBlitPass); } } if (renderingData.cameraData.isStereoEnabled) { renderer.EnqueuePass(m_EndXrRenderingPass); } #if UNITY_EDITOR m_UnlitGizmoRenderingPass.Setup(false); renderer.EnqueuePass(m_UnlitGizmoRenderingPass); if (renderingData.cameraData.isSceneViewCamera) { m_SceneViewDepthCopyPass.Setup(m_DepthTexture); renderer.EnqueuePass(m_SceneViewDepthCopyPass); } #endif }
public void Setup(ScriptableRenderer renderer, ref RenderingData renderingData) { Init(); Camera camera = renderingData.cameraData.camera; renderer.SetupPerObjectLightIndices(ref renderingData.cullResults, ref renderingData.lightData); RenderTextureDescriptor baseDescriptor = ScriptableRenderer.CreateRenderTextureDescriptor(ref renderingData.cameraData); RenderTextureDescriptor shadowDescriptor = baseDescriptor; shadowDescriptor.dimension = TextureDimension.Tex2D; bool mainLightShadows = false; if (renderingData.shadowData.supportsMainLightShadows) { mainLightShadows = m_MainLightShadowCasterPass.Setup(m_MainLightShadowmap, ref renderingData); if (mainLightShadows) { renderer.EnqueuePass(m_MainLightShadowCasterPass); } } if (renderingData.shadowData.supportsAdditionalLightShadows) { bool additionalLightShadows = m_AdditionalLightsShadowCasterPass.Setup(m_AdditionalLightsShadowmap, ref renderingData, renderer.maxVisibleAdditionalLights); if (additionalLightShadows) { renderer.EnqueuePass(m_AdditionalLightsShadowCasterPass); } } bool resolveShadowsInScreenSpace = mainLightShadows && renderingData.shadowData.requiresScreenSpaceShadowResolve; bool requiresDepthPrepass = resolveShadowsInScreenSpace || renderingData.cameraData.isSceneViewCamera || (renderingData.cameraData.requiresDepthTexture && (!CanCopyDepth(ref renderingData.cameraData))); // For now VR requires a depth prepass until we figure out how to properly resolve texture2DMS in stereo requiresDepthPrepass |= renderingData.cameraData.isStereoEnabled; renderer.EnqueuePass(m_SetupForwardRenderingPass); camera.GetComponents(m_AfterDepthpasses); camera.GetComponents(m_AfterOpaquePasses); camera.GetComponents(m_AfterOpaquePostProcessPasses); camera.GetComponents(m_AfterSkyboxPasses); camera.GetComponents(m_AfterTransparentPasses); camera.GetComponents(m_AfterRenderPasses); if (requiresDepthPrepass) { m_DepthOnlyPass.Setup(baseDescriptor, m_DepthTexture, SampleCount.One); renderer.EnqueuePass(m_DepthOnlyPass); foreach (var pass in m_AfterDepthpasses) { renderer.EnqueuePass(pass.GetPassToEnqueue(m_DepthOnlyPass.descriptor, m_DepthTexture)); } } if (resolveShadowsInScreenSpace) { m_ScreenSpaceShadowResolvePass.Setup(baseDescriptor, m_ScreenSpaceShadowmap); renderer.EnqueuePass(m_ScreenSpaceShadowResolvePass); } bool requiresRenderToTexture = RequiresIntermediateColorTexture(ref renderingData.cameraData, baseDescriptor) || m_AfterDepthpasses.Count != 0 || m_AfterOpaquePasses.Count != 0 || m_AfterOpaquePostProcessPasses.Count != 0 || m_AfterSkyboxPasses.Count != 0 || m_AfterTransparentPasses.Count != 0 || m_AfterRenderPasses.Count != 0 || Display.main.requiresBlitToBackbuffer || renderingData.killAlphaInFinalBlit; RenderTargetHandle colorHandle = RenderTargetHandle.CameraTarget; RenderTargetHandle depthHandle = RenderTargetHandle.CameraTarget; var sampleCount = (SampleCount)renderingData.cameraData.msaaSamples; if (requiresRenderToTexture) { colorHandle = m_ColorAttachment; depthHandle = m_DepthAttachment; m_CreateLightweightRenderTexturesPass.Setup(baseDescriptor, colorHandle, depthHandle, sampleCount); renderer.EnqueuePass(m_CreateLightweightRenderTexturesPass); } if (renderingData.cameraData.isStereoEnabled) { renderer.EnqueuePass(m_BeginXrRenderingPass); } var perObjectFlags = ScriptableRenderer.GetPerObjectLightFlags(renderingData.lightData.mainLightIndex, renderingData.lightData.additionalLightsCount); m_SetupLightweightConstants.Setup(renderer.maxVisibleAdditionalLights, renderer.perObjectLightIndices); renderer.EnqueuePass(m_SetupLightweightConstants); m_RenderOpaqueForwardPass.Setup(baseDescriptor, colorHandle, depthHandle, ScriptableRenderer.GetCameraClearFlag(camera), camera.backgroundColor, perObjectFlags); renderer.EnqueuePass(m_RenderOpaqueForwardPass); foreach (var pass in m_AfterOpaquePasses) { renderer.EnqueuePass(pass.GetPassToEnqueue(baseDescriptor, colorHandle, depthHandle)); } if (renderingData.cameraData.postProcessEnabled && renderingData.cameraData.postProcessLayer.HasOpaqueOnlyEffects(renderer.postProcessingContext)) { m_CreatePostOpaqueColorPass.Setup(baseDescriptor, m_ColorAttachmentAfterOpaquePost, sampleCount); renderer.EnqueuePass(m_CreatePostOpaqueColorPass); m_OpaquePostProcessPass.Setup(baseDescriptor, colorHandle, m_ColorAttachmentAfterOpaquePost, true, false); renderer.EnqueuePass(m_OpaquePostProcessPass); colorHandle = m_ColorAttachmentAfterOpaquePost; foreach (var pass in m_AfterOpaquePostProcessPasses) { renderer.EnqueuePass(pass.GetPassToEnqueue(baseDescriptor, colorHandle, depthHandle)); } } if (camera.clearFlags == CameraClearFlags.Skybox) { m_DrawSkyboxPass.Setup(colorHandle, depthHandle); renderer.EnqueuePass(m_DrawSkyboxPass); } foreach (var pass in m_AfterSkyboxPasses) { renderer.EnqueuePass(pass.GetPassToEnqueue(baseDescriptor, colorHandle, depthHandle)); } if (renderingData.cameraData.requiresDepthTexture && !requiresDepthPrepass) { m_CopyDepthPass.Setup(depthHandle, m_DepthTexture); renderer.EnqueuePass(m_CopyDepthPass); } if (renderingData.cameraData.requiresOpaqueTexture) { m_CopyColorPass.Setup(colorHandle, m_OpaqueColor); renderer.EnqueuePass(m_CopyColorPass); } m_RenderTransparentForwardPass.Setup(baseDescriptor, colorHandle, depthHandle, perObjectFlags); renderer.EnqueuePass(m_RenderTransparentForwardPass); foreach (var pass in m_AfterTransparentPasses) { renderer.EnqueuePass(pass.GetPassToEnqueue(baseDescriptor, colorHandle, depthHandle)); } #if UNITY_EDITOR m_LitGizmoRenderingPass.Setup(true); renderer.EnqueuePass(m_LitGizmoRenderingPass); #endif bool afterRenderExists = m_AfterRenderPasses.Count != 0; // if we have additional filters // we need to stay in a RT if (afterRenderExists) { // perform post with src / dest the same if (renderingData.cameraData.postProcessEnabled) { m_CreatePostTransparentColorPass.Setup(baseDescriptor, m_ColorAttachmentAfterTransparentPost, sampleCount); renderer.EnqueuePass(m_CreatePostTransparentColorPass); m_PostProcessPass.Setup(baseDescriptor, colorHandle, m_ColorAttachmentAfterTransparentPost, false, false); renderer.EnqueuePass(m_PostProcessPass); colorHandle = m_ColorAttachmentAfterTransparentPost; } //execute after passes foreach (var pass in m_AfterRenderPasses) { renderer.EnqueuePass(pass.GetPassToEnqueue(baseDescriptor, colorHandle, depthHandle)); } //now blit into the final target if (colorHandle != RenderTargetHandle.CameraTarget) { if (m_CapturePass.Setup(colorHandle, renderingData.cameraData.captureActions)) { renderer.EnqueuePass(m_CapturePass); } m_FinalBlitPass.Setup(baseDescriptor, colorHandle, Display.main.requiresSrgbBlitToBackbuffer, renderingData.killAlphaInFinalBlit); renderer.EnqueuePass(m_FinalBlitPass); } } else { if (renderingData.cameraData.postProcessEnabled) { m_PostProcessPass.Setup(baseDescriptor, colorHandle, RenderTargetHandle.CameraTarget, false, renderingData.cameraData.camera.targetTexture == null); renderer.EnqueuePass(m_PostProcessPass); } else if (colorHandle != RenderTargetHandle.CameraTarget) { if (m_CapturePass.Setup(colorHandle, renderingData.cameraData.captureActions)) { renderer.EnqueuePass(m_CapturePass); } m_FinalBlitPass.Setup(baseDescriptor, colorHandle, Display.main.requiresSrgbBlitToBackbuffer, renderingData.killAlphaInFinalBlit); renderer.EnqueuePass(m_FinalBlitPass); } } if (renderingData.cameraData.isStereoEnabled) { renderer.EnqueuePass(m_EndXrRenderingPass); } #if UNITY_EDITOR m_UnlitGizmoRenderingPass.Setup(false); renderer.EnqueuePass(m_UnlitGizmoRenderingPass); if (renderingData.cameraData.isSceneViewCamera) { m_SceneViewDepthCopyPass.Setup(m_DepthTexture); renderer.EnqueuePass(m_SceneViewDepthCopyPass); } #endif }