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();
            }
        }
Exemplo n.º 2
0
        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);
        }
Exemplo n.º 3
0
        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);
        }
Exemplo n.º 4
0
        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);
            }
        }
Exemplo n.º 5
0
        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);
        }