Ejemplo n.º 1
0
    public PostProcessingGraphicsScreen(IServiceLocator services)
      : base(services.GetInstance<IGraphicsService>())
    {
      _sampleFramework = services.GetInstance<SampleFramework>();

      _spriteBatch = new SpriteBatch(GraphicsService.GraphicsDevice);
      _clearGBufferRenderer = new ClearGBufferRenderer(GraphicsService);
      _rebuildZBufferRenderer = new RebuildZBufferRenderer(GraphicsService);
      _meshRenderer = new MeshRenderer();
      _skyRenderer = new SkyRenderer(GraphicsService);
      _billboardRenderer = new BillboardRenderer(GraphicsService, 2048);

      Scene = new Scene();
      PostProcessors = new PostProcessorChain(GraphicsService);

      // Use 2D texture for reticle.
      var contentManager = services.GetInstance<ContentManager>();
      _reticle = contentManager.Load<Texture2D>("Reticle");

      // Use the sprite font of the GUI.
      var uiContentManager = services.GetInstance<ContentManager>("UIContent");
      var spriteFont = uiContentManager.Load<SpriteFont>("UI Themes/BlendBlue/Default");
      DebugRenderer = new DebugRenderer(GraphicsService, spriteFont)
      {
        DefaultColor = new Color(0, 0, 0),
        DefaultTextPosition = new Vector2F(10),
      };
    }
Ejemplo n.º 2
0
    public DistortionFilter(IGraphicsService graphicsService, ContentManager content)
      : base(graphicsService)
    {
      _billboardRenderer = new BillboardRenderer(GraphicsService, 512)
      {
        EnableSoftParticles = true,
      };

      _effect = content.Load<Effect>("PostProcessing/DistortionFilter");
      _viewportSizeParameter = _effect.Parameters["ViewportSize"];
      _strengthParameter = _effect.Parameters["Strength"];
      _sourceTextureParameter = _effect.Parameters["SourceTexture"];
      _distortionTextureParameter = _effect.Parameters["DistortionTexture"];

      // The distortion texture can have a lower resolution to improve performance.
      DistortionTexture = new RenderTarget2D(
        GraphicsService.GraphicsDevice,
        320,
        180,
        false, SurfaceFormat.Color,
        DepthFormat.None);

      Scene = new Scene();

      Strength = 0.01f;
    }
Ejemplo n.º 3
0
        public SampleGraphicsScreen(IServiceLocator services)
            : base(services.GetInstance<IGraphicsService>())
        {
            _sampleFramework = services.GetInstance<SampleFramework>();

              Name = "SampleScreen";
              ClearBackground = false;
              BackgroundColor = new Color(220, 220, 220);
              DrawReticle = false;
              UseFixedWidthFont = false;

              // Use 2D texture for reticle.
              var contentManager = services.GetInstance<ContentManager>();
              _reticle = contentManager.Load<Texture2D>("Reticle");

              // Get the sprite fonts used in the UI theme.
              var uiContentManager = services.GetInstance<ContentManager>("UIContent");
              _defaultFont = uiContentManager.Load<SpriteFont>("UI Themes/BlendBlue/Default");
              _fixedWidthFont = uiContentManager.Load<SpriteFont>("UI Themes/BlendBlue/Console");

              // Set up 2D camera such that (0, 0) is upper, left corner of screen and
              // (screenWidth, screenHeight) is lower, right corner of screen.
              var graphicsDevice = GraphicsService.GraphicsDevice;
              int screenWidth = graphicsDevice.PresentationParameters.BackBufferWidth;
              int screenHeight = graphicsDevice.PresentationParameters.BackBufferHeight;
              var projection = new OrthographicProjection
              {
            Near = 0, Far = 2000,
            Left = 0, Right = screenWidth,
            Top = 0, Bottom = screenHeight,
              };
              var camera = new Camera(projection);
              _cameraNode2D = new CameraNode(camera)
              {
            PoseWorld = new Pose(new Vector3F(0, 0, 1000)),
              };

              // Initialize renderers.
              _spriteBatch = new SpriteBatch(graphicsDevice);
              _meshRenderer = new MeshRenderer();
              _billboardRenderer = new BillboardRenderer(GraphicsService, 2048);
              DebugRenderer2D = new DebugRenderer(GraphicsService, _defaultFont)
              {
            SpriteFont = _defaultFont,
            DefaultColor = new Color(0, 0, 0),
            DefaultTextPosition = new Vector2F(10)
              };
              DebugRenderer = new DebugRenderer(GraphicsService, _defaultFont)
              {
            SpriteFont = _defaultFont,
            DefaultColor = new Color(0, 0, 0),
            DefaultTextPosition = new Vector2F(10)
              };

              Scene = new Scene();
        }
Ejemplo n.º 4
0
        //--------------------------------------------------------------
        /// <summary>
        /// Initializes a new instance of the <see cref="BasicGraphicsScreen"/> class.
        /// </summary>
        /// <param name="services">The services.</param>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="services"/> is <see langword="null"/>.
        /// </exception>
        public BasicGraphicsScreen(IServiceLocator services)
            : base(services?.GetInstance<IGraphicsService>())
        {
            if (services == null)
                throw new ArgumentNullException(nameof(services));

            _meshRenderer = new MeshRenderer();
            _billboardRenderer = new BillboardRenderer(GraphicsService, 2048);

            var contentManager = services.GetInstance<ContentManager>();
            var spriteFont = contentManager.Load<SpriteFont>("DigitalRune.Editor.Game/Fonts/DejaVuSans");
            DebugRenderer = new DebugRenderer(GraphicsService, spriteFont);

            Scene = new Scene();
        }
Ejemplo n.º 5
0
    public BillboardSample(Microsoft.Xna.Framework.Game game)
      : base(game)
    {
      SampleFramework.IsMouseVisible = false;
      var delegateGraphicsScreen = new DelegateGraphicsScreen(GraphicsService)
      {
        RenderCallback = Render,
      };
      GraphicsService.Screens.Insert(0, delegateGraphicsScreen);

      // Add a custom game object which controls the camera.
      _cameraObject = new CameraObject(Services);
      GameObjectService.Objects.Add(_cameraObject);

      // In this example we need three renderers:
      // The MeshRenderer handles MeshNodes.
      _meshRenderer = new MeshRenderer();

      // The BillboardRenderer handles BillboardNodes and ParticleSystemNodes.
      _billboardRenderer = new BillboardRenderer(GraphicsService, 2048);

      // The DebugRenderer is used to draw text.
      var spriteFont = UIContentManager.Load<SpriteFont>("UI Themes/BlendBlue/Default");
      _debugRenderer = new DebugRenderer(GraphicsService, spriteFont);

      // Create a new empty scene.
      _scene = new Scene();

      // Add the camera node to the scene.
      _scene.Children.Add(_cameraObject.CameraNode);

      // Add a few models to the scene.
      var sandbox = ContentManager.Load<ModelNode>("Sandbox/Sandbox").Clone();
      _scene.Children.Add(sandbox);

      // Add some lights to the scene which have the same properties as the lights 
      // of BasicEffect.EnableDefaultLighting().
      SceneSample.InitializeDefaultXnaLights(_scene);

      var texture = new PackedTexture(ContentManager.Load<Texture2D>("Billboard/BillboardReference"));

      // ----- View plane-aligned billboards with variations.
      // View plane-aligned billboards are rendered parallel to the screen.
      // The up-axis of the BillboardNode determines the up direction of the 
      // billboard.
      var pose0 = new Pose(new Vector3F(-9, 1.0f, 1.5f));
      var pose1 = pose0;
      var billboard = new ImageBillboard(texture);
      var billboardNode = new BillboardNode(billboard);
      billboardNode.Name = "View plane-aligned\nVarying color\nVarying alpha";
      billboardNode.PoseWorld = pose1;
      _scene.Children.Add(billboardNode);

      pose1.Position.Z -= 1;
      billboardNode = new BillboardNode(billboard);
      billboardNode.PoseWorld = pose1;
      billboardNode.Color = new Vector3F(1, 0, 0);
      billboardNode.Alpha = 0.9f;
      _scene.Children.Add(billboardNode);

      pose1.Position.Z -= 1;
      billboardNode = new BillboardNode(billboard);
      billboardNode.PoseWorld = pose1;
      billboardNode.Color = new Vector3F(0, 1, 0);
      billboardNode.Alpha = 0.7f;
      _scene.Children.Add(billboardNode);

      pose1.Position.Z -= 1;
      billboardNode = new BillboardNode(billboard);
      billboardNode.PoseWorld = pose1;
      billboardNode.Color = new Vector3F(0, 0, 1);
      billboardNode.Alpha = 0.3f;
      _scene.Children.Add(billboardNode);

      // ----- View plane-aligned billboards with different blend modes
      // blend mode = 0 ... additive blend
      // blend mode = 1 ... alpha blend
      pose0.Position.X += 2;
      pose1 = pose0;
      billboard = new ImageBillboard(texture);
      billboard.BlendMode = 0.0f;
      billboardNode = new BillboardNode(billboard);
      billboardNode.Name = "View plane-aligned\nVarying blend mode";
      billboardNode.PoseWorld = pose1;
      _scene.Children.Add(billboardNode);

      pose1.Position.Z -= 1;
      billboard = new ImageBillboard(texture);
      billboard.BlendMode = 0.333f;
      billboardNode = new BillboardNode(billboard);
      billboardNode.PoseWorld = pose1;
      _scene.Children.Add(billboardNode);

      pose1.Position.Z -= 1;
      billboard = new ImageBillboard(texture);
      billboard.BlendMode = 0.667f;
      billboardNode = new BillboardNode(billboard);
      billboardNode.PoseWorld = pose1;
      _scene.Children.Add(billboardNode);

      pose1.Position.Z -= 1;
      billboard = new ImageBillboard(texture);
      billboard.BlendMode = 1.0f;
      billboardNode = new BillboardNode(billboard);
      billboardNode.PoseWorld = pose1;
      _scene.Children.Add(billboardNode);

      // ----- View plane-aligned billboards with alpha test
      pose0.Position.X += 2;
      pose1 = pose0;
      billboard = new ImageBillboard(texture);
      billboard.AlphaTest = 0.9f;
      billboardNode = new BillboardNode(billboard);
      billboardNode.Name = "View plane-aligned\nVarying reference alpha";
      billboardNode.PoseWorld = pose1;
      _scene.Children.Add(billboardNode);

      pose1.Position.Z -= 1;
      billboard = new ImageBillboard(texture);
      billboard.AlphaTest = 0.667f;
      billboardNode = new BillboardNode(billboard);
      billboardNode.PoseWorld = pose1;
      _scene.Children.Add(billboardNode);

      pose1.Position.Z -= 1;
      billboard = new ImageBillboard(texture);
      billboard.AlphaTest = 0.333f;
      billboardNode = new BillboardNode(billboard);
      billboardNode.PoseWorld = pose1;
      _scene.Children.Add(billboardNode);

      pose1.Position.Z -= 1;
      billboard = new ImageBillboard(texture);
      billboard.AlphaTest = 0.0f;
      billboardNode = new BillboardNode(billboard);
      billboardNode.PoseWorld = pose1;
      _scene.Children.Add(billboardNode);

      // ----- View plane-aligned billboards with different scale and rotation
      pose0.Position.X += 2;
      pose1 = pose0;
      billboard = new ImageBillboard(texture);
      billboard.Orientation = BillboardOrientation.ViewPlaneAligned;
      billboardNode = new BillboardNode(billboard);
      billboardNode.Name = "View plane-aligned\nVarying scale\nVarying rotation";
      billboardNode.PoseWorld = pose1;
      billboardNode.ScaleLocal = new Vector3F(0.4f);
      _scene.Children.Add(billboardNode);

      pose1.Position.Z -= 1;
      billboardNode = billboardNode.Clone();
      billboardNode.Name = null;
      billboardNode.PoseWorld = pose1 * new Pose(Matrix33F.CreateRotationZ(MathHelper.ToRadians(-15)));
      billboardNode.ScaleLocal = new Vector3F(0.6f);
      _scene.Children.Add(billboardNode);

      pose1.Position.Z -= 1;
      billboardNode = billboardNode.Clone();
      billboardNode.Name = null;
      billboardNode.PoseWorld = pose1 * new Pose(Matrix33F.CreateRotationZ(MathHelper.ToRadians(-30)));
      billboardNode.ScaleLocal = new Vector3F(0.8f);
      _scene.Children.Add(billboardNode);

      pose1.Position.Z -= 1;
      billboardNode = billboardNode.Clone();
      billboardNode.Name = null;
      billboardNode.PoseWorld = pose1 * new Pose(Matrix33F.CreateRotationZ(MathHelper.ToRadians(-45)));
      billboardNode.ScaleLocal = new Vector3F(1.0f);
      _scene.Children.Add(billboardNode);

      // ----- Viewpoint-oriented billboards
      // Viewpoint-orientated billboards always face the player. (The face normal 
      // points directly to the camera.)
      pose0.Position.X += 2;
      pose1 = pose0;
      billboard = new ImageBillboard(texture);
      billboard.Orientation = BillboardOrientation.ViewpointOriented;
      billboardNode = new BillboardNode(billboard);
      billboardNode.Name = "Viewpoint-oriented";
      billboardNode.PoseWorld = pose1;
      _scene.Children.Add(billboardNode);

      pose1.Position.Z -= 1;
      billboardNode = new BillboardNode(billboard);
      billboardNode.PoseWorld = pose1;
      _scene.Children.Add(billboardNode);

      pose1.Position.Z -= 1;
      billboardNode = new BillboardNode(billboard);
      billboardNode.PoseWorld = pose1;
      _scene.Children.Add(billboardNode);

      pose1.Position.Z -= 1;
      billboardNode = new BillboardNode(billboard);
      billboardNode.PoseWorld = pose1;
      _scene.Children.Add(billboardNode);

      // ----- Screen-aligned billboards
      // View plane-aligned billboards and screen-aligned billboards are similar. The 
      // billboards are rendered parallel to the screen. The orientation can be changed 
      // by rotating the BillboardNode. The difference is that the orientation of view 
      // plane-aligned billboards is relative to world space and the orientation of 
      // screen-aligned billboards is relative to view space.
      // Screen-aligned billboards are, for example, used for text label.
      pose0.Position.X += 2;
      pose1 = pose0;
      billboard = new ImageBillboard(texture);
      billboard.Orientation = BillboardOrientation.ScreenAligned;
      billboardNode = new BillboardNode(billboard);
      billboardNode.Name = "Screen-aligned";
      billboardNode.PoseWorld = pose1;
      _scene.Children.Add(billboardNode);

      pose1.Position.Z -= 1;
      billboardNode = new BillboardNode(billboard);
      billboardNode.PoseWorld = pose1;
      _scene.Children.Add(billboardNode);

      pose1.Position.Z -= 1;
      billboardNode = new BillboardNode(billboard);
      billboardNode.PoseWorld = pose1;
      _scene.Children.Add(billboardNode);

      pose1.Position.Z -= 1;
      billboardNode = new BillboardNode(billboard);
      billboardNode.PoseWorld = pose1;
      _scene.Children.Add(billboardNode);

      // ----- Axial, view plane-aligned billboards
      pose0.Position.X += 2;
      pose1 = pose0;
      billboard = new ImageBillboard(texture);
      billboard.Orientation = BillboardOrientation.AxialViewPlaneAligned;
      billboardNode = new BillboardNode(billboard);
      billboardNode.Name = "Axial, view plane-aligned";
      billboardNode.PoseWorld = pose1;
      _scene.Children.Add(billboardNode);

      pose1.Position.Z -= 1;
      billboardNode = billboardNode.Clone();
      billboardNode.Name = null;
      billboardNode.PoseWorld = pose1;
      _scene.Children.Add(billboardNode);

      pose1.Position.Z -= 1;
      billboardNode = new BillboardNode(billboard);
      billboardNode.PoseWorld = pose1;
      _scene.Children.Add(billboardNode);

      pose1.Position.Z -= 1;
      billboardNode = new BillboardNode(billboard);
      billboardNode.PoseWorld = pose1;
      _scene.Children.Add(billboardNode);

      // ----- Axial, viewpoint-oriented billboards
      pose0.Position.X += 2;
      pose1 = pose0;
      billboard = new ImageBillboard(texture);
      billboard.Orientation = BillboardOrientation.AxialViewpointOriented;
      billboardNode = new BillboardNode(billboard);
      billboardNode.Name = "Axial, viewpoint-oriented";
      billboardNode.PoseWorld = pose1;
      _scene.Children.Add(billboardNode);

      pose1.Position.Z -= 1;
      billboardNode = new BillboardNode(billboard);
      billboardNode.PoseWorld = pose1;
      _scene.Children.Add(billboardNode);

      pose1.Position.Z -= 1;
      billboardNode = new BillboardNode(billboard);
      billboardNode.PoseWorld = pose1;
      _scene.Children.Add(billboardNode);

      pose1.Position.Z -= 1;
      billboardNode = new BillboardNode(billboard);
      billboardNode.PoseWorld = pose1;
      _scene.Children.Add(billboardNode);

      // ----- World-oriented billboards
      // World-oriented billboards have a fixed orientation in world space. The 
      // orientation is determine by the BillboardNode.
      pose0.Position.X += 2;
      pose1 = pose0;
      pose1.Orientation *= Matrix33F.CreateRotationY(0.2f);
      billboard = new ImageBillboard(texture);
      billboard.Orientation = BillboardOrientation.WorldOriented;
      billboardNode = new BillboardNode(billboard);
      billboardNode.Name = "World-oriented";
      billboardNode.PoseWorld = pose1;
      _scene.Children.Add(billboardNode);

      pose1.Position.Z -= 1;
      pose1.Orientation *= Matrix33F.CreateRotationY(0.2f);
      billboardNode = new BillboardNode(billboard);
      billboardNode.PoseWorld = pose1 * new Pose(Matrix33F.CreateRotationZ(MathHelper.ToRadians(15)));
      _scene.Children.Add(billboardNode);

      pose1.Position.Z -= 1;
      pose1.Orientation *= Matrix33F.CreateRotationY(0.2f);
      billboardNode = new BillboardNode(billboard);
      billboardNode.PoseWorld = pose1 * new Pose(Matrix33F.CreateRotationZ(MathHelper.ToRadians(30)));
      _scene.Children.Add(billboardNode);

      pose1.Position.Z -= 1;
      pose1.Orientation *= Matrix33F.CreateRotationY(0.2f);
      billboardNode = new BillboardNode(billboard);
      billboardNode.PoseWorld = pose1 * new Pose(Matrix33F.CreateRotationZ(MathHelper.ToRadians(45)));
      _scene.Children.Add(billboardNode);

      // ----- Animated billboards
      // DigitalRune Graphics supports "texture atlases". I.e. textures can be packed 
      // together into a single, larger texture file. A PackedTexture can describe a 
      // single texture packed into a texture atlas or a tile set packed into a 
      // texture atlas. In this example the "beeWingFlap" is a set of three tiles.
      // Tile sets can be used for sprite animations. (The animation is set below in 
      // Update().)
      pose0.Position.X += 2;
      pose1 = pose0;
      texture = new PackedTexture("Bee", ContentManager.Load<Texture2D>("Particles/beeWingFlap"), Vector2F.Zero, Vector2F.One, 3, 1);
      _animatedBillboard = new ImageBillboard(texture);
      billboardNode = new BillboardNode(_animatedBillboard);
      billboardNode.Name = "Animated billboards";
      billboardNode.PoseWorld = pose1;
      _scene.Children.Add(billboardNode);

      pose1.Position.Z -= 1;
      billboardNode = new BillboardNode(_animatedBillboard);
      billboardNode.PoseWorld = pose1;
      _scene.Children.Add(billboardNode);

      pose1.Position.Z -= 1;
      billboardNode = new BillboardNode(_animatedBillboard);
      billboardNode.PoseWorld = pose1;
      _scene.Children.Add(billboardNode);

      // Use DebugRenderer to draw node names above billboard nodes.
      foreach (var node in _scene.GetDescendants().OfType<BillboardNode>())
        _debugRenderer.DrawText(node.Name, node.PoseWorld.Position + new Vector3F(0, 1, 0), new Vector2F(0.5f), Color.Yellow, false);
    }
Ejemplo n.º 6
0
    //--------------------------------------------------------------
    #region Creation & Cleanup
    //--------------------------------------------------------------

    public DeferredGraphicsScreen(IServiceLocator services)
      : base(services.GetInstance<IGraphicsService>())
    {
      _sampleFramework = services.GetInstance<SampleFramework>();
      var contentManager = services.GetInstance<ContentManager>();

      SpriteBatch = GraphicsService.GetSpriteBatch();

      // Let's create the necessary scene node renderers:
#if !XBOX360
      TerrainRenderer = new TerrainRenderer(GraphicsService);
#endif
      MeshRenderer = new MeshRenderer();

      // The _opaqueMeshSceneRenderer combines all renderers for opaque
      // (= not alpha blended) meshes.
      _opaqueMeshSceneRenderer = new SceneRenderer();
#if !XBOX360
      _opaqueMeshSceneRenderer.Renderers.Add(TerrainRenderer);
#endif
      _opaqueMeshSceneRenderer.Renderers.Add(MeshRenderer);

      _decalRenderer = new DecalRenderer(GraphicsService);
      _billboardRenderer = new BillboardRenderer(GraphicsService, 2048)
      {
        EnableSoftParticles = true,

        // If you have an extreme amount of particles that cover the entire screen,
        // you can turn on offscreen rendering to improve performance.
        //EnableOffscreenRendering = true,
      };

      // The AlphaBlendSceneRenderer combines all renderers for transparent
      // (= alpha blended) objects.
      AlphaBlendSceneRenderer = new SceneRenderer();
      AlphaBlendSceneRenderer.Renderers.Add(MeshRenderer);
      AlphaBlendSceneRenderer.Renderers.Add(_billboardRenderer);
      AlphaBlendSceneRenderer.Renderers.Add(new WaterRenderer(GraphicsService));
      AlphaBlendSceneRenderer.Renderers.Add(new FogSphereRenderer(GraphicsService));
      AlphaBlendSceneRenderer.Renderers.Add(new VolumetricLightRenderer(GraphicsService));

#if !XBOX360
      // Update terrain clipmaps. (Only necessary if TerrainNodes are used.)
      _terrainClipmapRenderer = new TerrainClipmapRenderer(GraphicsService);
#endif

      // Renderer for cloud maps. (Only necessary if LayeredCloudMaps are used.)
      _cloudMapRenderer = new CloudMapRenderer(GraphicsService);

      // Renderer for SceneCaptureNodes. See also SceneCapture2DSample.
      // In the constructor we specify a method which is called in SceneCaptureRenderer.Render() 
      // when the scene must be rendered for the SceneCaptureNodes.
      SceneCaptureRenderer = new SceneCaptureRenderer(context =>
      {
        // Get scene nodes which are visible by the current camera.
        CustomSceneQuery sceneQuery = Scene.Query<CustomSceneQuery>(context.CameraNode, context);
        // Render scene (with post-processing, with lens flares, no debug rendering, no reticle).
        RenderScene(sceneQuery, context, true, true, false, false);
      });

      // Renderer for PlanarReflectionNodes. See also PlanarReflectionSample.
      // In the constructor we specify a method which is called in PlanarReflectionRenderer.Render() 
      // to create the reflection images.
      _planarReflectionRenderer = new PlanarReflectionRenderer(context =>
      {
        // Get scene nodes which are visible by the current camera.
        CustomSceneQuery sceneQuery = Scene.Query<CustomSceneQuery>(context.CameraNode, context);

        var planarReflectionNode = (PlanarReflectionNode)context.ReferenceNode;

        // Planar reflections are often for WaterNodes. These nodes should not be rendered 
        // into their own reflection map because when the water surface is displaced by waves, 
        // some waves could be visible in the reflection. 
        // --> Remove the water node from the renderable nodes. (In our samples, the water
        // node is the parent of the reflection node.)
        if (planarReflectionNode.Parent is WaterNode)
        {
          var index = sceneQuery.RenderableNodes.IndexOf(planarReflectionNode.Parent);
          if (index >= 0)
            sceneQuery.RenderableNodes[index] = null;
        }

        // Render scene (no post-processing, no lens flares, no debug rendering, no reticle).
        RenderScene(sceneQuery, context, false, false, false, false);
      });

      _waterWavesRenderer = new WaterWavesRenderer(GraphicsService);

      // The shadow map renderer renders a depth image from the viewpoint of the light and
      // stores it in LightNode.Shadow.ShadowMap.
      ShadowMapRenderer = new ShadowMapRenderer(context =>
      {
        var query = context.Scene.Query<ShadowCasterQuery>(context.CameraNode, context);
        if (query.ShadowCasters.Count == 0)
          return false;

        _opaqueMeshSceneRenderer.Render(query.ShadowCasters, context);
        return true;
      });

      // The shadow mask renderer evaluates the shadow maps, does shadow filtering 
      // and stores the resulting shadow factor in a screen space image 
      //(see LightNode.Shadow.ShadowMask/ShadowMaskChannel).
      ShadowMaskRenderer = new ShadowMaskRenderer(GraphicsService, 2);

      // Optionally, we can blur the shadow mask to make the shadows smoother.
      var blur = new Blur(GraphicsService)
      {
        IsAnisotropic = false,
        IsBilateral = true,
        EdgeSoftness = 0.05f,
        Scale = 1f,
        Enabled = false,  // Disable blur by default.
      };
      blur.InitializeGaussianBlur(11, 3, true);
      ShadowMaskRenderer.Filter = blur;

      // Renderers which create the intermediate render targets:
      // Those 2 renderers are implemented in this sample. Those functions could
      // be implemented directly in this class but we have created separate classes
      // to make the code more readable.
      _gBufferRenderer = new GBufferRenderer(GraphicsService, _opaqueMeshSceneRenderer, _decalRenderer);
      LightBufferRenderer = new LightBufferRenderer(GraphicsService);

      // Other specialized renderers:
      _lensFlareRenderer = new LensFlareRenderer(GraphicsService);
      _skyRenderer = new SkyRenderer(GraphicsService);
      _fogRenderer = new FogRenderer(GraphicsService);
      _internalDebugRenderer = new DebugRenderer(GraphicsService, null);
      _rebuildZBufferRenderer = new RebuildZBufferRenderer(GraphicsService);

      Scene = new Scene();

      // This screen needs a HDR filter to map high dynamic range values back to
      // low dynamic range (LDR).
      PostProcessors = new PostProcessorChain(GraphicsService);
      PostProcessors.Add(new HdrFilter(GraphicsService)
      {
        EnableBlueShift = true,
        BlueShiftCenter = 0.0004f,
        BlueShiftRange = 0.5f,
        //BlueShiftColor = new Vector3F(1.05f / 4f, 0.97f / 4f, 1.27f / 4f),  // Default physically-based blue-shift
        BlueShiftColor = new Vector3F(0.25f, 0.25f, 0.7f),  // More dramatic blue-shift
        MinExposure = 0,
        MaxExposure = 10,
        BloomIntensity = 1,
        BloomThreshold = 0.6f,
      });
      _underwaterPostProcessor = new UnderwaterPostProcessor(GraphicsService, contentManager);
      PostProcessors.Add(_underwaterPostProcessor);

      // Use 2D texture for reticle.
      _reticle = contentManager.Load<Texture2D>("Reticle");

      // Use the sprite font of the GUI.
      var uiContentManager = services.GetInstance<ContentManager>("UIContent");
      var spriteFont = uiContentManager.Load<SpriteFont>("UI Themes/BlendBlue/Default");
      DebugRenderer = new DebugRenderer(GraphicsService, spriteFont)
      {
        DefaultColor = new Color(0, 0, 0),
        DefaultTextPosition = new Vector2F(10),
      };

      EnableLod = true;
    }