예제 #1
0
        protected virtual void DrawView(RenderContext context, RenderDrawContext drawContext)
        {
            var renderSystem = context.RenderSystem;

            // Z Prepass
            var lightProbes = LightProbes && GBufferRenderStage != null;

            if (lightProbes)
            {
                // Note: Baking lightprobe before GBuffer prepass because we are updating some cbuffer parameters needed by Opaque pass that GBuffer pass might upload early
                PrepareLightprobeConstantBuffer(context);

                // TODO: Temporarily using ShadowMap shader
                using (drawContext.QueryManager.BeginProfile(Color.Green, CompositingProfilingKeys.GBuffer))
                    using (drawContext.PushRenderTargetsAndRestore())
                    {
                        drawContext.CommandList.Clear(drawContext.CommandList.DepthStencilBuffer, DepthStencilClearOptions.DepthBuffer);
                        drawContext.CommandList.SetRenderTarget(drawContext.CommandList.DepthStencilBuffer, null);

                        // Draw [main view | z-prepass stage]
                        renderSystem.Draw(drawContext, context.RenderView, GBufferRenderStage);
                    }

                // Bake lightprobes against Z-buffer
                BakeLightProbes(context, drawContext);
            }

            using (drawContext.PushRenderTargetsAndRestore())
            {
                // Draw [main view | main stage]
                if (OpaqueRenderStage != null)
                {
                    using (drawContext.QueryManager.BeginProfile(Color.Green, CompositingProfilingKeys.Opaque))
                    {
                        renderSystem.Draw(drawContext, context.RenderView, OpaqueRenderStage);
                    }
                }

                // Draw [main view | transparent stage]
                Texture depthStencilSRV = null;
                if (TransparentRenderStage != null)
                {
                    // Some transparent shaders will require the depth as a shader resource - resolve it only once and set it here
                    using (drawContext.QueryManager.BeginProfile(Color.Green, CompositingProfilingKeys.Transparent))
                        using (drawContext.PushRenderTargetsAndRestore())
                        {
                            depthStencilSRV = ResolveDepthAsSRV(drawContext);

                            renderSystem.Draw(drawContext, context.RenderView, TransparentRenderStage);
                        }
                }

                var colorTargetIndex = OpaqueRenderStage?.OutputValidator.Find(typeof(ColorTargetSemantic)) ?? -1;
                if (colorTargetIndex == -1)
                {
                    return;
                }

                // Resolve MSAA targets
                var renderTargets = currentRenderTargets;
                var depthStencil  = currentDepthStencil;
                if (actualMultisampleCount != MultisampleCount.None)
                {
                    using (drawContext.QueryManager.BeginProfile(Color.Green, CompositingProfilingKeys.MsaaResolve))
                    {
                        ResolveMSAA(drawContext);
                    }

                    renderTargets = currentRenderTargetsNonMSAA;
                    depthStencil  = currentDepthStencilNonMSAA;
                }

                // Shafts if we have them
                if (LightShafts != null)
                {
                    using (drawContext.QueryManager.BeginProfile(Color.Green, CompositingProfilingKeys.LightShafts))
                    {
                        LightShafts.Draw(drawContext, depthStencil, renderTargets[colorTargetIndex]);
                    }
                }

                if (PostEffects != null)
                {
                    // Run post effects
                    // Note: OpaqueRenderStage can't be null otherwise colorTargetIndex would be -1
                    PostEffects.Draw(drawContext, OpaqueRenderStage.OutputValidator, renderTargets.Items, depthStencil, ViewOutputTarget);
                }
                else
                {
                    if (actualMultisampleCount != MultisampleCount.None)
                    {
                        using (drawContext.QueryManager.BeginProfile(Color.Green, CompositingProfilingKeys.MsaaResolve))
                        {
                            drawContext.CommandList.Copy(renderTargets[colorTargetIndex], ViewOutputTarget);
                        }
                    }
                }

                // Free the depth texture since we won't need it anymore
                if (depthStencilSRV != null)
                {
                    drawContext.Resolver.ReleaseDepthStenctilAsShaderResource(depthStencilSRV);
                }
            }
        }
예제 #2
0
        protected override void DrawCore(RenderContext context, RenderDrawContext drawContext)
        {
            var viewport = drawContext.CommandList.Viewport;

            using (drawContext.PushRenderTargetsAndRestore())
            {
                // Render Shadow maps
                shadowMapRenderer?.Draw(drawContext);

                if (VRSettings.Enabled && VRSettings.VRDevice != null)
                {
                    var isFullViewport = (int)viewport.X == 0 && (int)viewport.Y == 0 &&
                                         (int)viewport.Width == drawContext.CommandList.RenderTarget.ViewWidth &&
                                         (int)viewport.Height == drawContext.CommandList.RenderTarget.ViewHeight;
                    if (!isFullViewport)
                    {
                        return;
                    }

                    bool hasPostEffects = PostEffects != null, presentingVR = this == VRRenderers[VRRenderers.Count - 1];

                    Texture vrFullSurface;
                    using (drawContext.PushRenderTargetsAndRestore())
                    {
                        var currentRenderTarget     = drawContext.CommandList.RenderTarget;
                        var desiredRenderTargetSize = VRSettings.VRDevice.ActualRenderFrameSize;

                        if (desiredRenderTargetSize.Width != currentRenderTarget.Width || desiredRenderTargetSize.Height != currentRenderTarget.Height)
                        {
                            drawContext.CommandList.SetRenderTargets(null, null); // force to create and bind a new render target
                        }
                        PrepareRenderTargets(drawContext, desiredRenderTargetSize);

                        vrFullSurface = viewOutputTarget;

                        //draw per eye
                        using (context.SaveViewportAndRestore())
                            using (drawContext.PushRenderTargetsAndRestore())
                            {
                                ViewCount = 2;

                                for (var i = 0; i < 2; i++)
                                {
                                    drawContext.CommandList.SetRenderTargets(currentDepthStencil, currentRenderTargets.Count, currentRenderTargets.Items);

                                    var frameSize = VRSettings.VRDevice.ActualRenderFrameSize;
                                    drawContext.CommandList.SetViewport(new Viewport(i * frameSize.Width / 2, 0, frameSize.Width / 2, frameSize.Height));

                                    using (context.PushRenderViewAndRestore(VRSettings.RenderViews[i]))
                                    {
                                        // Clear render target and depth stencil
                                        if (i == 0)
                                        {
                                            Clear?.Draw(drawContext);
                                        }

                                        ViewIndex = i;

                                        // draw view, but skip post processing (it will not do it, since eye count > 1)
                                        DrawView(context, drawContext, i, 2);

                                        // last eye, draw post effects over both eyes if we have some
                                        if (hasPostEffects && i == 1)
                                        {
                                            if (presentingVR)
                                            {
                                                var renderTargetDescription = TextureDescription.New2D(frameSize.Width, frameSize.Height, 1, PixelFormat.R8G8B8A8_UNorm_SRgb, TextureFlags.ShaderResource | TextureFlags.RenderTarget);
                                                vrFullSurface = PushScopedResource(drawContext.GraphicsContext.Allocator.GetTemporaryTexture2D(renderTargetDescription));
                                            }

                                            PostEffects.Draw(drawContext, OpaqueRenderStage.OutputValidator, currentRenderTargets.Items, currentDepthStencil, vrFullSurface);
                                        }
                                    }
                                }

                                if (VRSettings.VRDevice.SupportsOverlays)
                                {
                                    foreach (var overlay in VRSettings.Overlays)
                                    {
                                        if (overlay != null && overlay.Texture != null)
                                        {
                                            overlay.Overlay.UpdateSurface(drawContext.CommandList, overlay.Texture);
                                        }
                                    }
                                }

                                // if we are on our last forward renderer and our scene is ready for submission
                                if (presentingVR)
                                {
                                    VRSettings.VRDevice.Commit(drawContext.CommandList, vrFullSurface);
                                }
                            }
                    }

                    //draw mirror if desired
                    if (VRSettings.CopyMirror)
                    {
                        CopyOrScaleTexture(drawContext, vrFullSurface, drawContext.CommandList.RenderTarget);
                    }
                }
                else
                {
                    PrepareRenderTargets(drawContext, new Size2((int)viewport.Width, (int)viewport.Height));

                    ViewCount = 1;
                    ViewIndex = 0;

                    //var sssMaterialIndexRenderTarget = GenerateSSSMaterialIndexRenderTarget(context, viewport);

                    using (drawContext.PushRenderTargetsAndRestore())
                    {
                        drawContext.CommandList.SetRenderTargets(currentDepthStencil, currentRenderTargets.Count, currentRenderTargets.Items);

                        // Clear render target and depth stencil
                        Clear?.Draw(drawContext);

                        DrawView(context, drawContext, 0, 1);
                    }
                }
            }

            // Clear intermediate results
            currentRenderTargets.Clear();
            currentRenderTargetsNonMSAA.Clear();
            currentDepthStencil        = null;
            currentDepthStencilNonMSAA = null;
        }