/// <summary> /// Creates a basic deferred rendering pipeline. /// </summary> /// <param name="serviceRegistry">The IServiceRegistry.</param> /// <param name="effectName">The name of the main effect.</param> /// <param name="prepassEffectName">The name of the light prepass effect.</param> /// <param name="clearColor">The clear color of the final frame buffer.</param> /// <param name="useShadows">A flag stating if shadows are available in this pipeline.</param> /// <param name="ui">A flag stating if a UI renderer should be added to the pipeline.</param> /// <param name="backgroundName">The name of the background texture.</param> public static void CreateDefaultDeferred(IServiceRegistry serviceRegistry, string effectName, string prepassEffectName, Color clearColor, bool useShadows, bool ui, string backgroundName) { if (serviceRegistry == null) { throw new ArgumentNullException("serviceRegistry"); } if (effectName == null) { throw new ArgumentNullException("effectName"); } var renderSystem = serviceRegistry.GetSafeServiceAs <RenderSystem>(); var graphicsService = serviceRegistry.GetSafeServiceAs <IGraphicsDeviceService>(); // Adds a light processor that will track all the entities that have a light component. // This will also handle the shadows (allocation, activation etc.). AddLightProcessor(serviceRegistry, graphicsService.GraphicsDevice, useShadows); // Create Main pass var mainPipeline = renderSystem.Pipeline; // Adds a camera setter that will automatically fill the parameters from the camera (matrices, fov etc.). mainPipeline.Renderers.Add(new CameraSetter(serviceRegistry)); // Adds a recursive pass to render the shadow maps // This will render all the meshes with a different effect for shadow casting. if (useShadows) { AddShadowMap(serviceRegistry, mainPipeline, effectName); } // Create G-buffer pass var gbufferPipeline = new RenderPipeline("GBuffer"); // Renders the G-buffer for opaque geometry. gbufferPipeline.Renderers.Add(new ModelRenderer(serviceRegistry, effectName + ".ParadoxGBufferShaderPass").AddOpaqueFilter()); var gbufferProcessor = new GBufferRenderProcessor(serviceRegistry, gbufferPipeline, graphicsService.GraphicsDevice.DepthStencilBuffer, false); // Add sthe G-buffer pass to the pipeline. mainPipeline.Renderers.Add(gbufferProcessor); // Performs the light prepass on opaque geometry. // Adds this pass to the pipeline. var lightDeferredProcessor = new LightingPrepassRenderer(serviceRegistry, prepassEffectName, graphicsService.GraphicsDevice.DepthStencilBuffer.Texture, gbufferProcessor.GBufferTexture); mainPipeline.Renderers.Add(lightDeferredProcessor); // Sets the render targets and clear them. Also sets the viewport. mainPipeline.Renderers.Add(new RenderTargetSetter(serviceRegistry) { ClearColor = clearColor, EnableClearDepth = false, RenderTarget = graphicsService.GraphicsDevice.BackBuffer, DepthStencil = graphicsService.GraphicsDevice.DepthStencilBuffer, Viewport = new Viewport(0, 0, graphicsService.GraphicsDevice.BackBuffer.Width, graphicsService.GraphicsDevice.BackBuffer.Height) }); // Draws a background from a texture. if (backgroundName != null) { mainPipeline.Renderers.Add(new BackgroundRenderer(serviceRegistry, backgroundName)); } // Prevents depth write since depth was already computed in G-buffer pas. mainPipeline.Renderers.Add(new RenderStateSetter(serviceRegistry) { DepthStencilState = graphicsService.GraphicsDevice.DepthStencilStates.DepthRead }); mainPipeline.Renderers.Add(new ModelRenderer(serviceRegistry, effectName).AddOpaqueFilter()); mainPipeline.Renderers.Add(new RenderTargetSetter(serviceRegistry) { EnableClearDepth = false, EnableClearTarget = false, RenderTarget = graphicsService.GraphicsDevice.BackBuffer, DepthStencil = graphicsService.GraphicsDevice.DepthStencilBuffer, Viewport = new Viewport(0, 0, graphicsService.GraphicsDevice.BackBuffer.Width, graphicsService.GraphicsDevice.BackBuffer.Height) }); // Renders transparent geometry. Depth stencil state is determined by the object to draw. //mainPipeline.Renderers.Add(new RenderStateSetter(serviceRegistry) { DepthStencilState = graphicsService.GraphicsDevice.DepthStencilStates.DepthRead }); mainPipeline.Renderers.Add(new ModelRenderer(serviceRegistry, effectName).AddTransparentFilter()); // Renders the UI. if (ui) { mainPipeline.Renderers.Add(new UIRenderer(serviceRegistry)); } graphicsService.GraphicsDevice.Parameters.Set(RenderingParameters.UseDeferred, true); }
/// <summary> /// Creates the rendering pipeline /// </summary> private void CreatePipeline() { var renderers = RenderSystem.Pipeline.Renderers; var width = GraphicsDevice.BackBuffer.Width; var height = GraphicsDevice.BackBuffer.Height; var viewport = new Viewport(0, 0, width, height); var clearColor = Color.Black; var effectName = "ParadoxCraftEffectMain"; var fowardEffectName = "ParadoxCraftEffectForward"; var prepassEffectName = "ParadoxCraftPrepassEffect"; // Adds a light processor that will track all the entities that have a light component. // This will also handle the shadows (allocation, activation etc.). var lightProcessor = Entities.GetProcessor <LightShadowProcessor>(); if (lightProcessor == null) { Entities.Processors.Add(new DynamicLightShadowProcessor(GraphicsDevice, false)); } // Camera renderers.Add(new CameraSetter(Services)); // Create G-buffer pass var gbufferPipeline = new RenderPipeline("GBuffer"); // Renders the G-buffer for opaque geometry. gbufferPipeline.Renderers.Add(new ModelRenderer(Services, effectName + ".ParadoxGBufferShaderPass").AddOpaqueFilter()); var gbufferProcessor = new GBufferRenderProcessor(Services, gbufferPipeline, GraphicsDevice.DepthStencilBuffer, false); // Add sthe G-buffer pass to the pipeline. renderers.Add(gbufferProcessor); // Performs the light prepass on opaque geometry. // Adds this pass to the pipeline. var lightDeferredProcessor = new LightingPrepassRenderer(Services, prepassEffectName, GraphicsDevice.DepthStencilBuffer, gbufferProcessor.GBufferTexture); renderers.Add(lightDeferredProcessor); renderers.Add(new RenderTargetSetter(Services) { ClearColor = clearColor, EnableClearDepth = false, RenderTarget = GraphicsDevice.BackBuffer, DepthStencil = GraphicsDevice.DepthStencilBuffer, Viewport = viewport }); renderers.Add(new RenderStateSetter(Services) { DepthStencilState = GraphicsDevice.DepthStencilStates.Default, RasterizerState = GraphicsDevice.RasterizerStates.CullBack }); // Renders all the meshes with the correct lighting. renderers.Add(new ModelRenderer(Services, fowardEffectName).AddLightForwardSupport()); // Blend atmoshpere inscatter on top renderers.Add(new AtmosphereRenderer(Services, Atmosphere, Sunlight)); // Wireframe mode if (isWireframe) { GraphicsDevice.Parameters.Set(Effect.RasterizerStateKey, RasterizerState.New(GraphicsDevice, new RasterizerStateDescription(CullMode.None) { FillMode = FillMode.Wireframe })); } GraphicsDevice.Parameters.Set(RenderingParameters.UseDeferred, true); }
/// <summary> /// Creates a basic deferred rendering pipeline. /// </summary> /// <param name="serviceRegistry">The IServiceRegistry.</param> /// <param name="effectName">The name of the main effect.</param> /// <param name="prepassEffectName">The name of the light prepass effect.</param> /// <param name="clearColor">The clear color of the final frame buffer.</param> /// <param name="useShadows">A flag stating if shadows are available in this pipeline.</param> /// <param name="ui">A flag stating if a UI renderer should be added to the pipeline.</param> /// <param name="backgroundName">The name of the background texture.</param> public static void CreateDefaultDeferred(IServiceRegistry serviceRegistry, string effectName, string prepassEffectName, Color clearColor, bool useShadows, bool ui, string backgroundName) { if (serviceRegistry == null) { throw new ArgumentNullException("serviceRegistry"); } if (effectName == null) { throw new ArgumentNullException("effectName"); } var renderSystem = serviceRegistry.GetSafeServiceAs <RenderSystem>(); var graphicsService = serviceRegistry.GetSafeServiceAs <IGraphicsDeviceService>(); #if SILICONSTUDIO_PARADOX_GRAPHICS_API_OPENGL var width = graphicsService.GraphicsDevice.DepthStencilBuffer.Width; var height = graphicsService.GraphicsDevice.DepthStencilBuffer.Height; // On OpenGL, intermediate texture are flipped and we cannot create a framebuffer with a user-generated attachment and a default one. // So we will render everything into a intermediate texture and draw it on screen at the end. var finalRenderTexture = Texture.New2D(graphicsService.GraphicsDevice, width, height, PixelFormat.R8G8B8A8_UNorm, TextureFlags.RenderTarget | TextureFlags.ShaderResource); var finalDepthBuffer = Texture.New2D(graphicsService.GraphicsDevice, width, height, PixelFormat.D32_Float, TextureFlags.DepthStencil | TextureFlags.ShaderResource); #else var finalRenderTexture = graphicsService.GraphicsDevice.BackBuffer; var finalDepthBuffer = graphicsService.GraphicsDevice.DepthStencilBuffer; #endif var readOnlyDepthBuffer = finalDepthBuffer.ToDepthStencilReadOnlyTexture(); // Adds a light processor that will track all the entities that have a light component. // This will also handle the shadows (allocation, activation etc.). AddLightProcessor(serviceRegistry, graphicsService.GraphicsDevice, useShadows); // Create Main pass var mainPipeline = renderSystem.Pipeline; // Adds a camera setter that will automatically fill the parameters from the camera (matrices, fov etc.). mainPipeline.Renderers.Add(new CameraSetter(serviceRegistry)); // Adds a recursive pass to render the shadow maps // This will render all the meshes with a different effect for shadow casting. if (useShadows) { AddShadowMap(serviceRegistry, mainPipeline, effectName); } // Create G-buffer pass var gbufferPipeline = new RenderPipeline("GBuffer"); // Renders the G-buffer for opaque geometry. gbufferPipeline.Renderers.Add(new ModelRenderer(serviceRegistry, effectName + ".ParadoxGBufferShaderPass").AddOpaqueFilter()); var gbufferProcessor = new GBufferRenderProcessor(serviceRegistry, gbufferPipeline, finalDepthBuffer, false); // Add sthe G-buffer pass to the pipeline. mainPipeline.Renderers.Add(gbufferProcessor); // Performs the light prepass on opaque geometry. // Adds this pass to the pipeline. var lightDeferredProcessor = new LightingPrepassRenderer(serviceRegistry, prepassEffectName, finalDepthBuffer, gbufferProcessor.GBufferTexture); mainPipeline.Renderers.Add(lightDeferredProcessor); // Sets the render targets and clear them. Also sets the viewport. mainPipeline.Renderers.Add(new RenderTargetSetter(serviceRegistry) { ClearColor = clearColor, EnableClearDepth = false, RenderTarget = finalRenderTexture, DepthStencil = finalDepthBuffer, Viewport = new Viewport(0, 0, finalRenderTexture.ViewWidth, finalRenderTexture.ViewHeight) }); // Draws a background from a texture. if (backgroundName != null) { mainPipeline.Renderers.Add(new BackgroundRenderer(serviceRegistry, backgroundName)); } // Prevents depth write since depth was already computed in G-buffer pas. mainPipeline.Renderers.Add(new RenderStateSetter(serviceRegistry) { DepthStencilState = graphicsService.GraphicsDevice.DepthStencilStates.DepthRead }); mainPipeline.Renderers.Add(new ModelRenderer(serviceRegistry, effectName).AddOpaqueFilter()); mainPipeline.Renderers.Add(new RenderTargetSetter(serviceRegistry) { EnableClearDepth = false, EnableClearTarget = false, RenderTarget = finalRenderTexture, DepthStencil = finalDepthBuffer, Viewport = new Viewport(0, 0, finalRenderTexture.ViewWidth, finalRenderTexture.ViewHeight) }); // Renders transparent geometry. Depth stencil state is determined by the object to draw. mainPipeline.Renderers.Add(new RenderStateSetter(serviceRegistry) { DepthStencilState = graphicsService.GraphicsDevice.DepthStencilStates.DepthRead }); mainPipeline.Renderers.Add(new ModelRenderer(serviceRegistry, effectName).AddTransparentFilter()); #if SILICONSTUDIO_PARADOX_GRAPHICS_API_OPENGL // on OpenGL, draw the final texture to the framebuffer mainPipeline.Renderers.Add(new RenderStateSetter(serviceRegistry) { DepthStencilState = graphicsService.GraphicsDevice.DepthStencilStates.None, BlendState = graphicsService.GraphicsDevice.BlendStates.Opaque }); mainPipeline.Renderers.Add(new RenderTargetSetter(serviceRegistry) { ClearColor = clearColor, EnableClearDepth = false, EnableClearStencil = false, EnableClearTarget = false, RenderTarget = graphicsService.GraphicsDevice.BackBuffer, DepthStencil = null, Viewport = new Viewport(0, 0, graphicsService.GraphicsDevice.BackBuffer.ViewWidth, graphicsService.GraphicsDevice.BackBuffer.ViewHeight) }); mainPipeline.Renderers.Add(new DelegateRenderer(serviceRegistry) { Render = (context => graphicsService.GraphicsDevice.DrawTexture(finalRenderTexture, true)) }); #endif // Renders the UI. if (ui) { mainPipeline.Renderers.Add(new UIRenderer(serviceRegistry)); } graphicsService.GraphicsDevice.Parameters.Set(RenderingParameters.UseDeferred, true); }