public override void Render(ScriptableRenderContext context, Camera[] cameras) { base.Render(context, cameras); RenderPipeline.BeginFrameRendering(cameras); GraphicsSettings.lightsUseLinearIntensity = true; SetupPerFrameShaderConstants(); // Sort cameras array by camera depth Array.Sort(cameras, m_CameraComparer); foreach (Camera camera in cameras) { RenderPipeline.BeginCameraRendering(camera); var cameraContext = CameraContext.Create(camera); Render(ref context, cameraContext); { var cmd = CommandBufferPool.Get(""); cmd.name = "After Camera Render"; #if UNITY_EDITOR if (cameraContext.SceneViewCamera) { m_TextureUtil.CopyTexture(cmd, CameraRenderTargetID.depth, BuiltinRenderTextureType.CameraTarget, true); } #endif cmd.ReleaseTemporaryRT(m_ShadowManager.ScreenSpaceShadowMapRTID); cmd.ReleaseTemporaryRT(CameraRenderTargetID.depthCopy); cmd.ReleaseTemporaryRT(CameraRenderTargetID.depth); cmd.ReleaseTemporaryRT(CameraRenderTargetID.color); cmd.ReleaseTemporaryRT(CameraRenderTargetID.copyColor); context.ExecuteCommandBuffer(cmd); CommandBufferPool.Release(cmd); } context.Submit(); m_ShadowManager.ReleaseRenderTarget(); } }
public bool Cull(ref ScriptableRenderContext context , CameraContext cameraContext , float maxShadowDistance) { if (!CullResults.GetCullingParameters(cameraContext.Camera, cameraContext.StereoEnabled, out cullingParameters)) { return(false); } cullingParameters.shadowDistance = Mathf.Min(maxShadowDistance, cameraContext.Camera.farClipPlane); #if UNITY_EDITOR // Emit scene view UI if (cameraContext.SceneViewCamera) { ScriptableRenderContext.EmitWorldGeometryForSceneView(cameraContext.Camera); } #endif CullResults.Cull(ref cullingParameters, context, ref m_CullResults); return(true); }
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); }
private void SetupIntermediateRenderTextures(CommandBuffer cmd, FrameRenderingConfiguration renderingConfig, int msaaSamples, CameraContext cameraContext, RenderTargetIdentifier ColorRT) { var camera = cameraContext.Camera; RenderTextureDescriptor baseDesc; if (LightweightUtils.HasFlag(renderingConfig, FrameRenderingConfiguration.Stereo)) { baseDesc = XRSettings.eyeTextureDesc; } else { baseDesc = new RenderTextureDescriptor(camera.pixelWidth, camera.pixelHeight); } float renderScale = (camera.cameraType == CameraType.Game) ? m_Asset.RenderScale : 1.0f; baseDesc.width = (int)((float)baseDesc.width * renderScale); baseDesc.height = (int)((float)baseDesc.height * renderScale); // TODO: Might be worth caching baseDesc for allocation of other targets (Screen-space Shadow Map?) if (m_RequireDepthTexture) { var depthRTDesc = baseDesc; depthRTDesc.colorFormat = RenderTextureFormat.Depth; depthRTDesc.depthBufferBits = kDepthStencilBufferBits; cmd.GetTemporaryRT(CameraRenderTargetID.depth, depthRTDesc, FilterMode.Bilinear); if (LightweightUtils.HasFlag(renderingConfig, FrameRenderingConfiguration.DepthCopy)) { cmd.GetTemporaryRT(CameraRenderTargetID.depthCopy, depthRTDesc, FilterMode.Bilinear); } } var colorRTDesc = baseDesc; colorRTDesc.colorFormat = m_ColorFormat; colorRTDesc.depthBufferBits = kDepthStencilBufferBits; // TODO: does the color RT always need depth? colorRTDesc.sRGB = true; colorRTDesc.msaaSamples = msaaSamples; colorRTDesc.enableRandomWrite = false; // When offscreen camera current rendertarget is CameraTarget if (!cameraContext.IsOffscreenCamera) { cmd.GetTemporaryRT(CameraRenderTargetID.color, colorRTDesc, FilterMode.Bilinear); m_CurrCameraColorRT = ColorRT; } // When BeforeTransparent PostFX is enabled and only one effect is in the stack we need to create a temp // color RT to blit the effect. if (m_RequireCopyColor) { cmd.GetTemporaryRT(CameraRenderTargetID.copyColor, colorRTDesc, FilterMode.Point); } }
public void SetupIntermediateResources(FrameRenderingConfiguration renderingConfig, ref ScriptableRenderContext context, CameraContext cameraContext, RenderTargetIdentifier colorRT) { CommandBuffer cmd = CommandBufferPool.Get("Setup Intermediate Resources"); int msaaSamples = (cameraContext.IsOffscreenCamera) ? Math.Min(cameraContext.Camera.targetTexture.antiAliasing, m_Asset.MSAASampleCount) : m_Asset.MSAASampleCount; msaaSamples = (LightweightUtils.HasFlag(renderingConfig, FrameRenderingConfiguration.Msaa)) ? msaaSamples : 1; m_CurrCameraColorRT = BuiltinRenderTextureType.CameraTarget; if (LightweightUtils.HasFlag(renderingConfig, FrameRenderingConfiguration.IntermediateTexture) || m_RequireDepthTexture) { SetupIntermediateRenderTextures(cmd, renderingConfig, msaaSamples, cameraContext, colorRT); } context.ExecuteCommandBuffer(cmd); CommandBufferPool.Release(cmd); }
private void EndForwardRendering(ref ScriptableRenderContext context, FrameRenderingConfiguration renderingConfig, CameraContext cameraContext) { // No additional rendering needs to be done if this is an off screen rendering camera if (cameraContext.IsOffscreenCamera) { return; } var camera = cameraContext.Camera; m_TextureUtil.Blit(context, m_TextureUtil.CurrCameraColorRT, renderingConfig, camera); if (LightweightUtils.HasFlag(renderingConfig, FrameRenderingConfiguration.Stereo)) { context.StopMultiEye(camera); context.StereoEndRender(camera); } }
private void BeginForwardRendering(ref ScriptableRenderContext context, FrameRenderingConfiguration renderingConfig, CameraContext cameraContext) { RenderTargetIdentifier colorRT = BuiltinRenderTextureType.CameraTarget; RenderTargetIdentifier depthRT = BuiltinRenderTextureType.None; StereoRendering.Start(ref context, renderingConfig, cameraContext.Camera); CommandBuffer cmd = CommandBufferPool.Get("SetCameraRenderTarget"); bool intermediateTexture = LightweightUtils.HasFlag(renderingConfig, FrameRenderingConfiguration.IntermediateTexture); if (intermediateTexture) { if (!cameraContext.IsOffscreenCamera) { colorRT = m_TextureUtil.CurrCameraColorRT; } if (m_TextureUtil.RequireDepthTexture) { depthRT = m_DepthRT; } } ClearFlag clearFlag = ClearFlag.None; CameraClearFlags cameraClearFlags = cameraContext.Camera.clearFlags; if (cameraClearFlags != CameraClearFlags.Nothing) { clearFlag |= ClearFlag.Depth; if (cameraClearFlags == CameraClearFlags.Color || cameraClearFlags == CameraClearFlags.Skybox) { clearFlag |= ClearFlag.Color; } } m_TextureUtil.SetRenderTarget(cmd, colorRT, depthRT, cameraContext.Camera.backgroundColor, clearFlag); // If rendering to an intermediate RT we resolve viewport on blit due to offset not being supported // while rendering to a RT. if (!intermediateTexture && !LightweightUtils.HasFlag(renderingConfig, FrameRenderingConfiguration.DefaultViewport)) { cmd.SetViewport(cameraContext.Camera.pixelRect); } context.ExecuteCommandBuffer(cmd); CommandBufferPool.Release(cmd); }
private void RenderObjectsWithError(ref ScriptableRenderContext context, FilterRenderersSettings filterSettings, SortFlags sortFlags, FilterResults visibleRenderers, CameraContext cameraContext) { if (m_ErrorMaterial != null) { DrawRendererSettings errorSettings = new DrawRendererSettings(cameraContext.Camera, s_LegacyPassNames[0]); for (int i = 1; i < s_LegacyPassNames.Length; ++i) { errorSettings.SetShaderPassName(i, s_LegacyPassNames[i]); } errorSettings.sorting.flags = sortFlags; errorSettings.rendererConfiguration = RendererConfiguration.None; errorSettings.SetOverrideMaterial(m_ErrorMaterial, 0); context.DrawRenderers(visibleRenderers, ref errorSettings, filterSettings); } }
private void AfterTransparent(ref ScriptableRenderContext context, FrameRenderingConfiguration config, CameraContext cameraContext) { if (!LightweightUtils.HasFlag(config, FrameRenderingConfiguration.PostProcess)) { return; } CommandBuffer cmd = CommandBufferPool.Get("After Transparent"); m_TextureUtil.RenderPostProcess(cmd, m_TextureUtil.CurrCameraColorRT, BuiltinRenderTextureType.CameraTarget, false, cameraContext.Camera); context.ExecuteCommandBuffer(cmd); CommandBufferPool.Release(cmd); }
private void RenderTransparents(ref ScriptableRenderContext context, RendererConfiguration config, FilterResults visibleRenderers, CameraContext cameraContext) { var transparentSettings = new DrawRendererSettings(cameraContext.Camera, m_LitPassName); transparentSettings.SetShaderPassName(1, m_UnlitPassName); transparentSettings.sorting.flags = SortFlags.CommonTransparent; transparentSettings.rendererConfiguration = config; var transparentFilterSettings = new FilterRenderersSettings(true) { renderQueueRange = RenderQueueRange.transparent }; context.DrawRenderers(visibleRenderers, ref transparentSettings, transparentFilterSettings); // Render objects that did not match any shader pass with error shader RenderObjectsWithError(ref context, transparentFilterSettings, SortFlags.None, visibleRenderers, cameraContext); }
private void AfterOpaque(ref ScriptableRenderContext context, FrameRenderingConfiguration config, CameraContext cameraContext) { if (!m_TextureUtil.RequireDepthTexture) { return; } CommandBuffer cmd = CommandBufferPool.Get("After Opaque"); cmd.SetGlobalTexture(CameraRenderTargetID.depth, m_DepthRT); bool setRenderTarget = false; RenderTargetIdentifier depthRT = m_DepthRT; var camera = cameraContext.Camera; // TODO: There's currently an issue in the PostFX stack that has a one frame delay when an effect is enabled/disabled // when an effect is disabled, HasOpaqueOnlyEffects returns true in the first frame, however inside render the effect // state is update, causing RenderPostProcess here to not blit to FinalColorRT. Until the next frame the RT will have garbage. if (LightweightUtils.HasFlag(config, FrameRenderingConfiguration.BeforeTransparentPostProcess)) { // When only have one effect in the stack we blit to a work RT then blit it back to active color RT. // This seems like an extra blit but it saves us a depth copy/blit which has some corner cases like msaa depth resolve. if (m_TextureUtil.RequireCopyColor) { m_TextureUtil.RenderPostProcess(cmd, m_TextureUtil.CurrCameraColorRT, m_CopyColorRT, true, camera); cmd.Blit(m_CopyColorRT, m_TextureUtil.CurrCameraColorRT); } else { m_TextureUtil.RenderPostProcess(cmd, m_TextureUtil.CurrCameraColorRT, m_TextureUtil.CurrCameraColorRT, true, camera); } setRenderTarget = true; m_TextureUtil.SetRenderTarget(cmd, m_TextureUtil.CurrCameraColorRT, m_DepthRT, camera.backgroundColor); } if (LightweightUtils.HasFlag(config, FrameRenderingConfiguration.DepthCopy)) { m_TextureUtil.CopyTexture(cmd, m_DepthRT, m_CopyDepth); depthRT = m_CopyDepth; setRenderTarget = true; } if (setRenderTarget) { m_TextureUtil.SetRenderTarget(cmd, m_TextureUtil.CurrCameraColorRT, depthRT, camera.backgroundColor); } context.ExecuteCommandBuffer(cmd); CommandBufferPool.Release(cmd); }
private void RenderOpaques(ref ScriptableRenderContext context, RendererConfiguration settings, FilterResults visibleRenderers, CameraContext cameraContext) { var camera = cameraContext.Camera; var opaqueDrawSettings = new DrawRendererSettings(camera, m_LitPassName); opaqueDrawSettings.SetShaderPassName(1, m_UnlitPassName); opaqueDrawSettings.sorting.flags = SortFlags.CommonOpaque; opaqueDrawSettings.rendererConfiguration = settings; var opaqueFilterSettings = new FilterRenderersSettings(true) { renderQueueRange = RenderQueueRange.opaque }; context.DrawRenderers(visibleRenderers, ref opaqueDrawSettings, opaqueFilterSettings); // Render objects that did not match any shader pass with error shader RenderObjectsWithError(ref context, opaqueFilterSettings, SortFlags.None, visibleRenderers, cameraContext); if (camera.clearFlags == CameraClearFlags.Skybox) { context.DrawSkybox(camera); } }
private void ForwardPass(List <VisibleLight> visibleLights, FrameRenderingConfiguration frameRenderingConfiguration, ref ScriptableRenderContext context, ref LightData lightData, CameraContext cameraContext, CullResults cullResults) { SetupShaderConstants(visibleLights, ref context, ref lightData, ref cullResults); RendererConfiguration rendererSettings = GetRendererSettings(ref lightData); BeginForwardRendering(ref context, frameRenderingConfiguration, cameraContext); RenderOpaques(ref context, rendererSettings, cullResults.visibleRenderers, cameraContext); AfterOpaque(ref context, frameRenderingConfiguration, cameraContext); RenderTransparents(ref context, rendererSettings, cullResults.visibleRenderers, cameraContext); AfterTransparent(ref context, frameRenderingConfiguration, cameraContext); EndForwardRendering(ref context, frameRenderingConfiguration, cameraContext); }
void Render(ref ScriptableRenderContext context, CameraContext cameraContext) { /// /// culling /// if (!m_CullingUtil.Cull(ref context, cameraContext, m_ShadowManager.MaxShadowDistance)) { return; } var visibleLights = m_CullingUtil.CullResults.visibleLights; /// /// setup lights & shadows /// LightData lightData; m_LightManager.InitializeLightData(visibleLights, out lightData, cameraContext.Camera); m_ShadowManager.ShadowPass(visibleLights, ref context, ref lightData, m_CullingUtil.CullResults, m_LightManager.GetLightUnsortedIndex(lightData.mainLightIndex), cameraContext.Camera.backgroundColor); /// /// setup /// var frameRenderingConfiguration = m_TextureUtil.SetupFrameRenderingConfiguration(cameraContext, m_ShadowManager); m_TextureUtil.SetupIntermediateResources(frameRenderingConfiguration, ref context, cameraContext, m_ColorRT); // SetupCameraProperties does the following: // Setup Camera RenderTarget and Viewport // VR Camera Setup and SINGLE_PASS_STEREO props // Setup camera view, proj and their inv matrices. // Setup properties: _WorldSpaceCameraPos, _ProjectionParams, _ScreenParams, _ZBufferParams, unity_OrthoParams // Setup camera world clip planes props // setup HDR keyword // Setup global time properties (_Time, _SinTime, _CosTime) context.SetupCameraProperties(cameraContext.Camera, cameraContext.StereoEnabled); if (LightweightUtils.HasFlag(frameRenderingConfiguration, FrameRenderingConfiguration.DepthPrePass)) { DepthPass(ref context, frameRenderingConfiguration, m_CullingUtil.CullResults.visibleRenderers, cameraContext.Camera); } if (m_ShadowManager.Shadows) { m_ShadowManager.ShadowCollectPass(visibleLights, ref context, ref lightData, frameRenderingConfiguration, cameraContext.Camera); } else { m_ShadowManager.SmallShadowBuffer(ref context); } /// /// forward pass /// /// * Clear /// * Opaque /// * AfterOpaque /// * Transparent /// * AfterTransparent /// * PostEffect /// ForwardPass(visibleLights, frameRenderingConfiguration, ref context, ref lightData, cameraContext, m_CullingUtil.CullResults); }