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); } } }
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; }