Example #1
0
 public static void Start(ref ScriptableRenderContext context, FrameRenderingConfiguration renderingConfiguration, Camera currentCamera)
 {
     if (LightweightUtils.HasFlag(renderingConfiguration, FrameRenderingConfiguration.Stereo))
     {
         context.StartMultiEye(currentCamera);
     }
 }
        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);
            }
        }
        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 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);
        }
        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 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);
        }
        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);
            }
        }
        void Blit(CommandBuffer cmd, FrameRenderingConfiguration renderingConfig, RenderTargetIdentifier sourceRT, RenderTargetIdentifier destRT, Camera camera, Material material = null)
        {
            cmd.SetGlobalTexture(m_BlitTexID, sourceRT);
            if (LightweightUtils.HasFlag(renderingConfig, FrameRenderingConfiguration.DefaultViewport))
            {
                cmd.Blit(sourceRT, destRT, material);
            }
            else
            {
                if (m_BlitQuad == null)
                {
                    m_BlitQuad = LightweightUtils.CreateQuadMesh(false);
                }

                SetRenderTarget(cmd, destRT, camera.backgroundColor);
                cmd.SetViewProjectionMatrices(Matrix4x4.identity, Matrix4x4.identity);
                cmd.SetViewport(camera.pixelRect);
                cmd.DrawMesh(m_BlitQuad, Matrix4x4.identity, material);
            }
        }
        public void CollectShadows(Camera camera, FrameRenderingConfiguration frameRenderingConfiguration, ref ScriptableRenderContext context)
        {
            CommandBuffer cmd = CommandBufferPool.Get("Collect Shadows");

            SetShadowCollectPassKeywords(cmd);

            // Note: The source isn't actually 'used', but there's an engine peculiarity (bug) that
            // doesn't like null sources when trying to determine a stereo-ized blit.  So for proper
            // stereo functionality, we use the screen-space shadow map as the source (until we have
            // a better solution).
            // An alternative would be DrawProcedural, but that would require further changes in the shader.
            cmd.SetRenderTarget(m_ScreenSpaceShadowmapTexture);
            cmd.ClearRenderTarget(true, true, Color.white);
            cmd.Blit(m_ScreenSpaceShadowmapTexture, m_ScreenSpaceShadowmapTexture, m_ScreenSpaceShadowsMaterial);

            LightweightUtils.StartStereoRendering(camera, ref context, frameRenderingConfiguration);

            context.ExecuteCommandBuffer(cmd);

            LightweightUtils.StopStereoRendering(camera, ref context, frameRenderingConfiguration);

            CommandBufferPool.Release(cmd);
        }
        private void DepthPass(ref ScriptableRenderContext context, FrameRenderingConfiguration frameRenderingConfiguration, FilterResults visibleRenderers, Camera camera)
        {
            CommandBuffer cmd = CommandBufferPool.Get("Depth Prepass");

            m_TextureUtil.SetRenderTarget(cmd, m_DepthRT, camera.backgroundColor, ClearFlag.Depth);
            context.ExecuteCommandBuffer(cmd);
            CommandBufferPool.Release(cmd);

            var opaqueDrawSettings = new DrawRendererSettings(camera, m_DepthPrepass);

            opaqueDrawSettings.sorting.flags = SortFlags.CommonOpaque;

            var opaqueFilterSettings = new FilterRenderersSettings(true)
            {
                renderQueueRange = RenderQueueRange.opaque
            };

            StereoRendering.Start(ref context, frameRenderingConfiguration, camera);

            context.DrawRenderers(visibleRenderers, ref opaqueDrawSettings, opaqueFilterSettings);

            StereoRendering.Stop(ref context, frameRenderingConfiguration, camera);
        }
        public void Blit(ScriptableRenderContext context, RenderTargetIdentifier currCameraColorRT, FrameRenderingConfiguration renderingConfig, Camera camera)
        {
            var cmd = CommandBufferPool.Get("Blit");

            if (m_IntermediateTextureArray)
            {
                cmd.Blit(currCameraColorRT, BuiltinRenderTextureType.CameraTarget);
            }
            else if (LightweightUtils.HasFlag(renderingConfig, FrameRenderingConfiguration.IntermediateTexture))
            {
                Material blitMaterial = m_BlitMaterial;
                if (LightweightUtils.HasFlag(renderingConfig, FrameRenderingConfiguration.Stereo))
                {
                    blitMaterial = null;
                }

                // If PostProcessing is enabled, it is already blit to CameraTarget.
                if (!LightweightUtils.HasFlag(renderingConfig, FrameRenderingConfiguration.PostProcess))
                {
                    Blit(cmd, renderingConfig, currCameraColorRT, BuiltinRenderTextureType.CameraTarget, camera, blitMaterial);
                }
            }

            SetRenderTarget(cmd, BuiltinRenderTextureType.CameraTarget, camera.backgroundColor);

            context.ExecuteCommandBuffer(cmd);
            CommandBufferPool.Release(cmd);
        }
Example #13
0
 public static void StopStereoRendering(Camera camera, ref ScriptableRenderContext context, FrameRenderingConfiguration renderingConfiguration)
 {
     if (CoreUtils.HasFlag(renderingConfiguration, FrameRenderingConfiguration.Stereo))
     {
         context.StopMultiEye(camera);
     }
 }
Example #14
0
 public static bool HasFlag(FrameRenderingConfiguration mask, FrameRenderingConfiguration flag)
 {
     return((mask & flag) != 0);
 }
        public void ShadowCollectPass(List <VisibleLight> visibleLights, ref ScriptableRenderContext context, ref LightData lightData, FrameRenderingConfiguration frameRenderingConfiguration,
                                      Camera currentCamera)
        {
            if (!m_ShadowSettings.screenSpace)
            {
                return;
            }

            CommandBuffer cmd = CommandBufferPool.Get("Collect Shadows");

            SetShadowCollectPassKeywords(cmd, visibleLights[lightData.mainLightIndex], ref lightData);

            // TODO: Support RenderScale for the SSSM target.  Should probably move allocation elsewhere, or at
            // least propogate RenderTextureDescriptor generation
            if (LightweightUtils.HasFlag(frameRenderingConfiguration, FrameRenderingConfiguration.Stereo))
            {
                var desc = XRSettings.eyeTextureDesc;
                desc.depthBufferBits = 0;
                desc.colorFormat     = m_ShadowSettings.screenspaceShadowmapTextureFormat;
                cmd.GetTemporaryRT(m_ScreenSpaceShadowMapRTID, desc, FilterMode.Bilinear);
            }
            else
            {
                cmd.GetTemporaryRT(m_ScreenSpaceShadowMapRTID, currentCamera.pixelWidth, currentCamera.pixelHeight, 0, FilterMode.Bilinear, m_ShadowSettings.screenspaceShadowmapTextureFormat);
            }

            // Note: The source isn't actually 'used', but there's an engine peculiarity (bug) that
            // doesn't like null sources when trying to determine a stereo-ized blit.  So for proper
            // stereo functionality, we use the screen-space shadow map as the source (until we have
            // a better solution).
            // An alternative would be DrawProcedural, but that would require further changes in the shader.
            cmd.Blit(m_ScreenSpaceShadowMapRT, m_ScreenSpaceShadowMapRT, m_ScreenSpaceShadowsMaterial);

            StereoRendering.Start(ref context, frameRenderingConfiguration, currentCamera);

            context.ExecuteCommandBuffer(cmd);

            StereoRendering.Stop(ref context, frameRenderingConfiguration, currentCamera);

            CommandBufferPool.Release(cmd);
        }