Пример #1
0
    // OnLoad() is called when the GameObject is added to the IGameObjectService.
    protected override void OnLoad()
    {
      // ----- Create prototype of a lava ball:

      // Use a sphere for physics simulation.
      _bodyPrototype = new RigidBody(new SphereShape(0.5f));

      // Load the graphics model.
      var content = _services.GetInstance<ContentManager>();
      _modelPrototype = content.Load<ModelNode>("LavaBall/LavaBall").Clone();

      // Attach a point light to the model. The light projects the glowing lava 
      // veins (cube map texture) onto the environment.
      _pointLight = new PointLight
      {
        Color = new Vector3F(1, 1, 1),
        DiffuseIntensity = 2,
        SpecularIntensity = 2,
        Range = 1.5f,
        Attenuation = 0.5f,
        Texture = content.Load<TextureCube>("LavaBall/LavaCubeMap"),
      };
      var pointLightNode = new LightNode(_pointLight);
      _modelPrototype.Children.Add(pointLightNode);

      // Get the emissive color binding of the material because the emissive color
      // will be animated.
      // The model contains one mesh node with a single material.
      var meshNode = (MeshNode)_modelPrototype.Children[0];
      var mesh = meshNode.Mesh;
      var material = mesh.Materials[0];

      // The material contains several effect bindings. The "EmissiveColor" is applied
      // in the "Material" pass. 
      // (For reference see material definition file: Samples\Media\LavaBall\Lava.drmat)
      _emissiveColorBinding = (ConstParameterBinding<Vector3>)material["Material"].ParameterBindings["EmissiveColor"];

      // Use the animation service to animate glow intensity of the lava.
      var animationService = _services.GetInstance<IAnimationService>();

      // Create an AnimatableProperty<float>, which stores the animation value.
      _glowIntensity = new AnimatableProperty<float>();

      // Create sine animation and play the animation back-and-forth.
      var animation = new SingleFromToByAnimation
      {
        From = 0.3f,
        To = 3.0f,
        Duration = TimeSpan.FromSeconds(1),
        EasingFunction = new SineEase { Mode = EasingMode.EaseInOut },
      };
      var clip = new AnimationClip<float>
      {
        Animation = animation,
        Duration = TimeSpan.MaxValue,
        LoopBehavior = LoopBehavior.Oscillate
      };
      animationService.StartAnimation(clip, _glowIntensity).AutoRecycle();
    }
Пример #2
0
    public ProjectedShadowSample(Microsoft.Xna.Framework.Game game)
    : base(game)
    {
      SampleFramework.IsMouseVisible = false;
      var delegateGraphicsScreen = new DelegateGraphicsScreen(GraphicsService)
      {
        RenderCallback = Render,
      };
      GraphicsService.Screens.Insert(0, delegateGraphicsScreen);

      // Create a new empty scene.
      _scene = new Scene();
      Services.Register(typeof(IScene), null, _scene);

      // Add a custom game object which controls the camera.
      _cameraObject = new CameraObject(Services);
      _cameraObject.ResetPose(new Vector3F(-8, 6, 8), -ConstantsF.PiOver4, -0.4f);
      GameObjectService.Objects.Add(_cameraObject);

      // Add a default light setup (ambient light + 3 directional lights).
      var defaultLightsObject = new DefaultLightsObject(Services);
      GameObjectService.Objects.Add(defaultLightsObject);

      // Get the main directional light.
      _mainDirectionalLightNode = ((LightNode)_scene.GetSceneNode("KeyLight"));

      // Add a ground plane model to the scene graph.
      var grid = ContentManager.Load<ModelNode>("Ground/Ground").Clone();
      grid.ScaleLocal = new Vector3F(0.3f);
      _scene.Children.Add(grid);

      // Add a tank model to the scene graph.
      var tank = ContentManager.Load<ModelNode>("Tank/tank").Clone();
      _scene.Children.Add(tank);

      // Remember the mesh nodes of tank node.
      _tankMeshNodes = tank.GetSubtree().Where(n => n is MeshNode).ToArray();

      // Create the renderers.
      _meshRenderer = new MeshRenderer();

      var spriteFont = UIContentManager.Load<SpriteFont>("UI Themes/BlendBlue/Default");
      _debugRenderer = new DebugRenderer(GraphicsService, spriteFont);

      _projectedShadowRenderer = new ProjectedShadowRenderer(GraphicsService)
      {
        // The plane onto which the shadows are projected. It is positioned a bit above the ground
        // plane to avoid z-fighting.
        ShadowedPlane = new Plane(new Vector3F(0, 1, 0), 0.01f),

        // The shadow color is a transparent black.
        ShadowColor = new Vector4F(0, 0, 0, 0.4f),

        // The light position is set in Update().
        //LightPosition = ...
      };
    }
Пример #3
0
    // OnUnload() is called when the GameObject is removed from the IGameObjectService.
    protected override void OnUnload()
    {
      _godRayFilter.Scale = _defaultScale;

      if (_directionalLightNode != null)
      {
        _directionalLightNode.SceneChanged -= OnDirectionalLightNodeChanged;
        _directionalLightNode = null;
      }
    }
Пример #4
0
    // OnLoad() is called when the GameObject is added to the IGameObjectService.
    protected override void OnLoad()
    {
      var ambientLight = new AmbientLight
      {
        //Color = new Vector3F(0.05333332f, 0.09882354f, 0.1819608f),  // XNA BasicEffect Values
        Color = new Vector3F(0.5f),                                    // Make ambient light brighter.
        Intensity = 1,
        HemisphericAttenuation = 1,
      };
      _ambientLightNode = new LightNode(ambientLight);

      var keyLight = new DirectionalLight
      {
        Color = new Vector3F(1, 0.9607844f, 0.8078432f),
        DiffuseIntensity = 1,
        SpecularIntensity = 1,
      };
      _keyLightNode = new LightNode(keyLight)
      {
        Name = "KeyLight",
        Priority = 10,   // This is the most important light.
        PoseWorld = new Pose(QuaternionF.CreateRotation(Vector3F.Forward, new Vector3F(-0.5265408f, -0.5735765f, -0.6275069f))),
      };

      var fillLight = new DirectionalLight
      {
        Color = new Vector3F(0.9647059f, 0.7607844f, 0.4078432f),
        DiffuseIntensity = 1,
        SpecularIntensity = 0,
      };
      _fillLightNode = new LightNode(fillLight)
      {
        Name = "FillLight",
        PoseWorld = new Pose(QuaternionF.CreateRotation(Vector3F.Forward, new Vector3F(0.7198464f, 0.3420201f, 0.6040227f))),
      };

      var backLight = new DirectionalLight
      {
        Color = new Vector3F(0.3231373f, 0.3607844f, 0.3937255f),
        DiffuseIntensity = 1,
        SpecularIntensity = 1,
      };
      _backLightNode = new LightNode(backLight)
      {
        Name = "BackLight",
        PoseWorld = new Pose(QuaternionF.CreateRotation(Vector3F.Forward, new Vector3F(0.4545195f, -0.7660444f, 0.4545195f))),
      };

      var scene = _services.GetInstance<IScene>();
      scene.Children.Add(_ambientLightNode);
      scene.Children.Add(_keyLightNode);
      scene.Children.Add(_fillLightNode);
      scene.Children.Add(_backLightNode);
    }
Пример #5
0
    public VarianceShadowSample(Microsoft.Xna.Framework.Game game)
      : base(game)
    {
      SampleFramework.IsMouseVisible = false;
      _graphicsScreen = new DeferredGraphicsScreen(Services)
      {
        // For debugging: Disable materials and only show light buffer.
        DebugMode = DeferredGraphicsDebugMode.VisualizeDiffuseLightBuffer
      };
      _graphicsScreen.DrawReticle = true;
      GraphicsService.Screens.Insert(0, _graphicsScreen);

      GameObjectService.Objects.Add(new DeferredGraphicsOptionsObject(Services));

      Services.Register(typeof(DebugRenderer), null, _graphicsScreen.DebugRenderer);
      Services.Register(typeof(IScene), null, _graphicsScreen.Scene);

      // Add gravity and damping to the physics simulation.
      Simulation.ForceEffects.Add(new Gravity());
      Simulation.ForceEffects.Add(new Damping());

      // Add a custom game object which controls the camera.
      var cameraGameObject = new CameraObject(Services);
      GameObjectService.Objects.Add(cameraGameObject);
      _graphicsScreen.ActiveCameraNode = cameraGameObject.CameraNode;

      GameObjectService.Objects.Add(new GrabObject(Services));

      // Create test scene.
      ShadowSample.CreateScene(Services, ContentManager, _graphicsScreen);

      // Get directional light created by the DynamicSkyObject and replace the default 
      // shadow with our custom VSM shadow.
      _lightNode = _graphicsScreen.Scene.GetDescendants().OfType<LightNode>().First(n => n.Shadow is CascadedShadow);
      _varianceShadow = new VarianceShadow
      {
        // If a target area is set, the VSM covers the given area.
        // If no target area is set, the VSM covers the area in front of the camera.
        TargetArea = new Aabb(new Vector3F(-100, 0, -100), new Vector3F(100, 50, 100)),
      };
      _lightNode.Shadow = _varianceShadow;

      // Apply a blur filter to the shadow map.
      _varianceShadow.Filter = new Blur(GraphicsService);
      _varianceShadow.Filter.InitializeGaussianBlur(11, 3, false);

      // Register our custom shadow map and shadow mask renderers.
      _graphicsScreen.ShadowMapRenderer.Renderers.Add(new VarianceShadowMapRenderer(_graphicsScreen.ShadowMapRenderer.RenderCallback));
      _graphicsScreen.ShadowMaskRenderer.Renderers.Add(new VarianceShadowMaskRenderer(GraphicsService));

      CreateGuiControls();
    }
        public int Compare(LightNode x, LightNode y)
        {
            if (x.Priority < y.Priority)
            {
                return(-1);
            }
            if (x.Priority > y.Priority)
            {
                return(+1);
            }

            return(x.SortTag.CompareTo(y.SortTag));
        }
Пример #7
0
        // Add light sources for standard three-point lighting.
        private static void AddLights(Scene scene)
        {
            var ambientLight = new AmbientLight
              {
            Color = new Vector3F(0.05333332f, 0.09882354f, 0.1819608f),
            Intensity = 1,
            HemisphericAttenuation = 0,
              };
              scene.Children.Add(new LightNode(ambientLight));

              var keyLight = new DirectionalLight
              {
            Color = new Vector3F(1, 0.9607844f, 0.8078432f),
            DiffuseIntensity = 1,
            SpecularIntensity = 1,
              };
              var keyLightNode = new LightNode(keyLight)
              {
            Name = "KeyLight",
            Priority = 10,   // This is the most important light.
            PoseWorld = new Pose(QuaternionF.CreateRotation(Vector3F.Forward, new Vector3F(-0.5265408f, -0.5735765f, -0.6275069f))),
              };
              scene.Children.Add(keyLightNode);

              var fillLight = new DirectionalLight
              {
            Color = new Vector3F(0.9647059f, 0.7607844f, 0.4078432f),
            DiffuseIntensity = 1,
            SpecularIntensity = 0,
              };
              var fillLightNode = new LightNode(fillLight)
              {
            Name = "FillLight",
            PoseWorld = new Pose(QuaternionF.CreateRotation(Vector3F.Forward, new Vector3F(0.7198464f, 0.3420201f, 0.6040227f))),
              };
              scene.Children.Add(fillLightNode);

              var backLight = new DirectionalLight
              {
            Color = new Vector3F(0.3231373f, 0.3607844f, 0.3937255f),
            DiffuseIntensity = 1,
            SpecularIntensity = 1,
              };
              var backLightNode = new LightNode(backLight)
              {
            Name = "BackLight",
            PoseWorld = new Pose(QuaternionF.CreateRotation(Vector3F.Forward, new Vector3F(0.4545195f, -0.7660444f, 0.4545195f))),
              };
              scene.Children.Add(backLightNode);
        }
Пример #8
0
        public void UpdateClipSubmesh(IGraphicsService graphicsService, LightNode node)
        {
            var clip = node.Clip;
              Debug.Assert(clip != null);

              // We have to update the submesh if it is null or disposed.
              //   Submesh == null                            --> Update
              //   Submesh != null && VertexBuffer.IsDisposed --> Update
              //   Submesh != null && VertexBuffer == null    --> This is the EmptyShape. No updated needed.
              if (ClipSubmesh == null || (ClipSubmesh.VertexBuffer != null && ClipSubmesh.VertexBuffer.IsDisposed))
              {
            ShapeMeshCache.GetMesh(graphicsService, clip.Shape, out ClipSubmesh, out ClipMatrix);

            // Add transform of Clip.
            ClipMatrix = clip.Pose * Matrix44F.CreateScale(clip.Scale) * ClipMatrix;
              }
        }
Пример #9
0
    // OnLoad() is called when the GameObject is added to the IGameObjectService.
    protected override void OnLoad()
    {
      var scene = (SceneNode)_services.GetInstance<IScene>();

      // Find the most important directional light. 
      _directionalLightNode = scene.GetDescendants()
                                   .OfType<LightNode>()
                                   .Where(ln => ln.Light is DirectionalLight)
                                   .OrderBy(ln => ln.Priority)
                                   .LastOrDefault();

      if (_directionalLightNode != null)
      {
        // This light node defines the direction of the god rays. Handle the 
        // SceneChanged event to update the GodRayFilter when the light node is
        // updated.
        _directionalLightNode.SceneChanged += OnDirectionalLightNodeChanged;

        // First time initialization:
        OnDirectionalLightNodeChanged(null, null);
      }
    }
Пример #10
0
    public ProjectedShadowSample2(Microsoft.Xna.Framework.Game game)
    : base(game)
    {
      SampleFramework.IsMouseVisible = false;
      var delegateGraphicsScreen = new DelegateGraphicsScreen(GraphicsService)
      {
        RenderCallback = Render,
      };
      GraphicsService.Screens.Insert(0, delegateGraphicsScreen);

      // The dude model uses a new ProjectedShadowSkinned.fx effect. This effect contains new 
      // parameters 'ShadowMatrix' and 'ShadowColor' which are not yet supported. When an mesh is 
      // loaded via the content manager, effect bindings are automatically created. This is done
      // by effect interpreters and effect binders. The graphics service uses several predefined
      // effect interpreter and binder classes to support the most common effect parameters. E.g.
      // the SceneEffectInterpreter and SceneEffectBinder handle parameters like 'World', 'View',
      // 'ViewProjection', 'CameraPosition', 'FogColor', etc. (see also class 
      // SceneEffectParameterSemantics).
      // We can add new effect interpreters/binders or we can add an entry to an existing 
      // interpreter/binder. Let's add entries to the standard SceneEffectInterpreter which creates 
      // meta-data for the new parameters:
      var sceneEffectInterpreter = GraphicsService.EffectInterpreters.OfType<SceneEffectInterpreter>().First();
      sceneEffectInterpreter.ParameterDescriptions.Add(
        "ShadowMatrix",
        (parameter, index) => new EffectParameterDescription(parameter, "ShadowMatrix", index, EffectParameterHint.Global));
      sceneEffectInterpreter.ParameterDescriptions.Add(
        "ShadowColor",
        (parameter, index) => new EffectParameterDescription(parameter, "ShadowColor", index, EffectParameterHint.Global));

      // Add entries to the standard SceneEffectBinder which create DelegateParameterBindings for 
      // the new parameters. The delegate bindings use callback methods to compute the parameter
      // value.
      var sceneEffectBinder = GraphicsService.EffectBinders.OfType<SceneEffectBinder>().First();
      sceneEffectBinder.MatrixBindings.Add(
        "ShadowMatrix",
        (effect, parameter, data) => new DelegateParameterBinding<Matrix>(effect, parameter, GetShadowMatrix));
      sceneEffectBinder.Vector4Bindings.Add(
        "ShadowColor",
        (effect, parameter, data) => new DelegateParameterBinding<Vector4>(effect, parameter, GetShadowColor));

      // Create a new empty scene.
      _scene = new Scene();
      Services.Register(typeof(IScene), null, _scene);

      // Add a custom game object which controls the camera.
      _cameraObject = new CameraObject(Services);
      _cameraObject.ResetPose(new Vector3F(-2, 2, 2), -ConstantsF.PiOver4, -0.4f);
      GameObjectService.Objects.Add(_cameraObject);

      // Add a default light setup (ambient light + 3 directional lights).
      var defaultLightsObject = new DefaultLightsObject(Services);
      GameObjectService.Objects.Add(defaultLightsObject);

      // Get the main directional light.
      _mainDirectionalLightNode = ((LightNode)_scene.GetSceneNode("KeyLight"));

      // Add a ground plane model to the scene graph.
      var grid = ContentManager.Load<ModelNode>("Ground/Ground").Clone();
      grid.ScaleLocal = new Vector3F(0.3f);
      _scene.Children.Add(grid);

      // Add a dude model to the scene graph.
      var dude = ContentManager.Load<ModelNode>("DudeWithProjectedShadow/Dude").Clone();
      dude.PoseWorld = new Pose(Matrix33F.CreateRotationY(ConstantsF.Pi));
      SampleHelper.EnablePerPixelLighting(dude);
      _scene.Children.Add(dude);

      // Start walk animation.
      StartDudeAnimation(dude);

      // Create the renderers.
      _meshRenderer = new MeshRenderer();

      _shadowColor = new Vector4(0, 0, 0, 0.4f);
    }
Пример #11
0
    public FacialAnimationSample(Microsoft.Xna.Framework.Game game)
      : base(game)
    {
      _graphicsScreen = new DeferredGraphicsScreen(Services) { DrawReticle = false };
      GraphicsService.Screens.Insert(0, _graphicsScreen);
      Services.Register(typeof(DebugRenderer), null, _graphicsScreen.DebugRenderer);
      Services.Register(typeof(IScene), null, _graphicsScreen.Scene);

      // Add a game object which adds some GUI controls for the deferred graphics
      // screen to the Options window.
      GameObjectService.Objects.Add(new DeferredGraphicsOptionsObject(Services));

      // Use a fixed camera.
      var projection = new PerspectiveProjection();
      projection.SetFieldOfView(
        ConstantsF.PiOver4,
        GraphicsService.GraphicsDevice.Viewport.AspectRatio,
        0.1f,
        10);
      var cameraNode = new CameraNode(new Camera(projection));
      cameraNode.LookAt(new Vector3F(0.15f, 0.15f, 0.5f), new Vector3F(0.1f, 0.15f, 0), Vector3F.Up);
      _graphicsScreen.Scene.Children.Add(cameraNode);
      _graphicsScreen.ActiveCameraNode = cameraNode;

      // Lighting setup:
      var keyLight = new LightNode(new Spotlight { DiffuseIntensity = 0.6f, SpecularIntensity = 0.4f });
      keyLight.LookAt(new Vector3F(-2, 2, 2), new Vector3F(), Vector3F.Up);
      _graphicsScreen.Scene.Children.Add(keyLight);

      var backLight = new LightNode(new Spotlight { DiffuseIntensity = 0.3f, SpecularIntensity = 0.3f });
      backLight.LookAt(new Vector3F(1, 0.5f, -2), new Vector3F(), Vector3F.Up);
      _graphicsScreen.Scene.Children.Add(backLight);
      
      var fillLight = new LightNode(new AmbientLight { HemisphericAttenuation = 1, Intensity = 0.1f });
      _graphicsScreen.Scene.Children.Add(fillLight);

      // The scene does not have a proper background. That's why the exposure is a 
      // bit off. --> Reduce the max exposure.
      var hdrFilter = _graphicsScreen.PostProcessors.OfType<HdrFilter>().First();
      hdrFilter.MaxExposure = 6;

      // Load the customized "Sintel" model (original: Durian Open Movie Project - http://www.sintel.org/).
      var model = ContentManager.Load<ModelNode>("Sintel/Sintel-Head").Clone();
      model.PoseWorld = new Pose(new Vector3F(0, 0, 0), Matrix33F.CreateRotationY(MathHelper.ToRadians(10)) * Matrix33F.CreateRotationX(-MathHelper.ToRadians(90)));
      _graphicsScreen.Scene.Children.Add(model);

      // The model consists of a root node and a mesh node.
      //  ModelNode "Sintel-Head"
      //    MeshNode "Sintel"
      _sintel = (MeshNode)model.Children[0];

      // The model contains two skeletal animations:
      // - "MOUTH-open" is just a single frame.
      // - "Test" is a short animation (250 frames).

      // In the Options window, we will add a slider to move the jaw.
      // Slider.Value = 0 ... mouth closed (default)
      _mouthClosedPose = SkeletonPose.Create(_sintel.Mesh.Skeleton);
      // Slider.Value = 1 ... mouth open (copied from the "MOUTH-open" animation)
      SkeletonKeyFrameAnimation mouthOpen = _sintel.Mesh.Animations["MOUTH-open"];
      _mouthOpenPose = SkeletonPose.Create(_sintel.Mesh.Skeleton);
      mouthOpen.GetValue(TimeSpan.Zero, ref _mouthOpenPose, ref _mouthOpenPose, ref _mouthOpenPose);

      // Turn the "Test" animation into an endless loop.
      _skeletalAnimation = new AnimationClip<SkeletonPose>(_sintel.Mesh.Animations["Test"])
      {
        Duration = TimeSpan.MaxValue,
        LoopBehavior = LoopBehavior.Cycle
      };

      // Mesh has several morph targets for facial animation, which are imported
      // automatically via the content pipeline. Unfortunately, the XNA content
      // pipeline cannot import morph target animations automatically.
      // In this demo, we will create a morph target animation in code.
      _morphingAnimation = CreateMorphingAnimation();

      CreateGuiControls();
    }
Пример #12
0
    // OnLoad() is called when the GameObject is added to the IGameObjectService.
    protected override void OnLoad()
    {
      var contentManager = _services.GetInstance<ContentManager>();
      
      if (_type == 1)
      {
        // A simple cube.
        RigidBody = new RigidBody(new BoxShape(1, 1, 1));
        ModelNode = contentManager.Load<ModelNode>("RustyCube/RustyCube").Clone();
      }
      else if (_type == 2)
      {
        // Another simple cube.
        RigidBody = new RigidBody(new BoxShape(1, 1, 1));
        ModelNode = contentManager.Load<ModelNode>("MetalGrateBox/MetalGrateBox").Clone();
      }
      else if (_type == 3)
      {
        // A TV-like box.
        RigidBody = new RigidBody(new BoxShape(1, 0.6f, 0.8f)) { UserData = "TV" };
        ModelNode = contentManager.Load<ModelNode>("TVBox/TVBox");

        if (ModelNode.Children.OfType<LightNode>().Count() == 0)
        {
          // This is the first time the "TVBox" is loaded.

          // Add a projector light to the model that projects the TV screen. The
          // TV screen is the emissive part of the TV mesh.
          var meshNode = ModelNode.Children.OfType<MeshNode>().First();
          var material = meshNode.Mesh.Materials.First(m => m.Name == "TestCard");

          // Get texture from material.
          // Note: In XNA the effect parameter type is Texture. In MonoGame it is Texture2D.
          Texture2D texture;
          EffectParameterBinding parameterBinding = material["Material"].ParameterBindings["EmissiveTexture"];
          if (parameterBinding is EffectParameterBinding<Texture>)
            texture = (Texture2D)((EffectParameterBinding<Texture>)parameterBinding).Value;
          else
            texture = ((EffectParameterBinding<Texture2D>)parameterBinding).Value;

          var projection = new PerspectiveProjection();
          projection.Near = 0.55f;
          projection.Far = 3.0f;
          projection.SetFieldOfView(MathHelper.ToRadians(60), 0.76f / 0.56f);

          var projectorLight = new ProjectorLight(texture, projection);
          projectorLight.Attenuation = 4;
          var projectorLightNode = new LightNode(projectorLight);
          projectorLightNode.LookAt(new Vector3F(0, 0.2f, 0), Vector3F.Zero, Vector3F.UnitZ);

          // Attach the projector light to the model.
          ModelNode.Children.Add(projectorLightNode);
        }

        ModelNode = ModelNode.Clone();
      }
      else if (_type == 4)
      {
        // A "magic" sphere with a colored point light.
        RigidBody = new RigidBody(new SphereShape(0.25f));
        ModelNode = contentManager.Load<ModelNode>("MagicSphere/MagicSphere");

        if (ModelNode.Children.OfType<LightNode>().Count() == 0)
        {
          // This is the first time the "MagicSphere" is loaded.

          // Change the size of the sphere.
          var meshNode = ModelNode.Children.OfType<MeshNode>().First();
          meshNode.ScaleLocal = new Vector3F(0.5f);

          // Disable shadows. (The sphere acts as a light source.)
          meshNode.CastsShadows = false;

          // Add a point light.
          var pointLight = new PointLight
          {
            Color = new Vector3F(1, 1, 1),
            DiffuseIntensity = 4,
            SpecularIntensity = 4,
            Range = 3,
            Attenuation = 1,
            Texture = contentManager.Load<TextureCube>("MagicSphere/ColorCube"),
          };
          var pointLightNode = new LightNode(pointLight)
          {
            // The point light uses shadow mapping to cast an omnidirectional shadow.
            Shadow = new CubeMapShadow
            {
              PreferredSize = 64,
            }
          };

          ModelNode.Children.Add(pointLightNode);
        }

        ModelNode = ModelNode.Clone();
      }
      else if (_type == 5)
      {
        // A sphere of glass (or "bubble").
        RigidBody = new RigidBody(new SphereShape(0.3f));
        ModelNode = contentManager.Load<ModelNode>("Bubble/Bubble").Clone();
        ModelNode.GetDescendants().OfType<MeshNode>().First().ScaleLocal = new Vector3F(0.3f);
      }
      else if (_type == 6)
      {
        // A rusty barrel with multiple levels of detail (LODs).
        RigidBody = new RigidBody(new CylinderShape(0.35f, 1));
        ModelNode = contentManager.Load<ModelNode>("Barrel/Barrel").Clone();
      }
      else
      {
        // A cube consisting of a frame and transparent sides.
        RigidBody = new RigidBody(new BoxShape(1, 1, 1));
        ModelNode = contentManager.Load<ModelNode>("GlassBox/GlassBox").Clone();
      }

      SampleHelper.EnablePerPixelLighting(ModelNode);

      // Set a random pose.
      var randomPosition = new Vector3F(
        RandomHelper.Random.NextFloat(-10, 10),
        RandomHelper.Random.NextFloat(2, 5),
        RandomHelper.Random.NextFloat(-20, 0));
      RigidBody.Pose = new Pose(randomPosition, RandomHelper.Random.NextQuaternionF());
      ModelNode.PoseWorld = RigidBody.Pose;

      // Add rigid body to physics simulation and model to scene.
      var simulation = _services.GetInstance<Simulation>();
      simulation.RigidBodies.Add(RigidBody);

      var scene = _services.GetInstance<IScene>();
      scene.Children.Add(ModelNode);
    }
Пример #13
0
        public void Render(IList<SceneNode> occluders, LightNode lightNode, SceneNodeRenderer renderer, RenderContext context)
        {
            if (context == null)
            throw new ArgumentNullException("context");

              context.ThrowIfCameraMissing();

              // ----- Sort occluders by type: IOcclusionProxy vs. SceneNode
              SortOccluders(occluders, renderer, context);
              Statistics.Occluders = _occlusionProxies.Count + _sceneNodes.Count;

              // ----- Update all IOcclusionProxy in background.
              if (_occlusionProxies.Count > 0)
              {
            if (EnableMultithreading)
              _updateTask = Parallel.Start(_updateOcclusionProxies);
            else
              UpdateOcclusionProxies();
              }

              // ----- Backup render state.
              var originalRenderTarget = context.RenderTarget;
              var originalViewport = context.Viewport;

              var graphicsService = context.GraphicsService;
              var graphicsDevice = graphicsService.GraphicsDevice;
              var originalRenderState = new RenderStateSnapshot(graphicsDevice);

              // ----- Camera properties
              var cameraNode = context.CameraNode;
              Matrix cameraView = (Matrix)cameraNode.View;
              var cameraProjection = cameraNode.Camera.Projection;
              Matrix cameraViewProjection = cameraView * cameraProjection;

              if (lightNode == null)
              {
            _lightHzbAvailable = false;
              }
              else
              {
            // ----- Render light HZB.
            _lightHzbAvailable = true;

            var shadow = lightNode.Shadow as CascadedShadow;
            if (shadow == null)
              throw new ArgumentException("LightNode expected to have a CascadedShadow.", "lightNode");

            // Set up orthographic camera similar to CascadedShadowMapRenderer.
            context.CameraNode = _orthographicCameraNode;

            // Part of camera frustum covered by shadow map.
            var maxShadowDistance = shadow.Distances[shadow.NumberOfCascades - 1];
            _splitVolume.SetFieldOfView(cameraProjection.FieldOfViewY, cameraProjection.AspectRatio, cameraProjection.Near, Math.Min(cameraProjection.Far, maxShadowDistance));

            // Find the bounding sphere of the camera frustum.
            Vector3F center;
            float radius;
            GetBoundingSphere(_splitVolume, out center, out radius);

            Matrix33F orientation = lightNode.PoseWorld.Orientation;
            Vector3F lightBackward = orientation.GetColumn(2);
            var orthographicProjection = (OrthographicProjection)_orthographicCameraNode.Camera.Projection;

            // Create a tight orthographic frustum around the cascade's bounding sphere.
            orthographicProjection.SetOffCenter(-radius, radius, -radius, radius, 0, 2 * radius);
            center = cameraNode.PoseWorld.ToWorldPosition(center);
            Vector3F cameraPosition = center + radius * lightBackward;
            Pose frustumPose = new Pose(cameraPosition, orientation);

            // For rendering the shadow map, move near plane back by MinLightDistance
            // to catch occluders in front of the cascade.
            orthographicProjection.Near = -shadow.MinLightDistance;
            _orthographicCameraNode.PoseWorld = frustumPose;

            Pose lightView = frustumPose.Inverse;
            Matrix lightViewProjection = (Matrix)lightView * orthographicProjection;

            _parameterCameraViewProj.SetValue(lightViewProjection);
            _parameterCameraNear.SetValue(orthographicProjection.Near);
            _parameterCameraFar.SetValue(orthographicProjection.Far);

            RenderOccluders(renderer, context);
            CreateDepthHierarchy(_lightHzb, context);

            // Set effect parameters for use in Query().
            _lightAabb = _orthographicCameraNode.Aabb;
            _parameterLightViewProj.SetValue(lightViewProjection);
            _parameterLightToCamera.SetValue(Matrix.Invert(lightViewProjection) * cameraViewProjection);

            context.CameraNode = cameraNode;
              }

              // ----- Render camera HZB.
              // Set camera parameters. (These effect parameters are also needed in Query()!)
              _cameraAabb = cameraNode.Aabb;
              _parameterCameraViewProj.SetValue(cameraViewProjection);
              _parameterCameraNear.SetValue(cameraProjection.Near);
              _parameterCameraFar.SetValue(cameraProjection.Far);

              var lodCameraNode = context.LodCameraNode;
              if (lodCameraNode != null)
              {
            // Enable distance culling.
            _parameterCameraPosition.SetValue((Vector3)lodCameraNode.PoseWorld.Position);
            float yScale = Math.Abs(lodCameraNode.Camera.Projection.ToMatrix44F().M11);
            _parameterNormalizationFactor.SetValue(1.0f / yScale * cameraNode.LodBias * context.LodBias);
              }
              else
              {
            // Disable distance culling.
            _parameterCameraPosition.SetValue(new Vector3());
            _parameterNormalizationFactor.SetValue(0);
              }

              RenderOccluders(renderer, context);
              CreateDepthHierarchy(_cameraHzb, context);

              _sceneNodes.Clear();
              _occlusionProxies.Clear();

              // Restore render state.
              graphicsDevice.SetRenderTarget(null);
              originalRenderState.Restore();

              context.RenderTarget = originalRenderTarget;
              context.Viewport = originalViewport;
        }
Пример #14
0
 public void Render(IList<SceneNode> occluders, LightNode lightNode, RenderContext context)
 {
     Render(occluders, lightNode, null, context);
 }
Пример #15
0
    public CompositeShadowSample(Microsoft.Xna.Framework.Game game)
      : base(game)
    {
      SampleFramework.IsMouseVisible = false;
      _graphicsScreen = new DeferredGraphicsScreen(Services)
      {
        // For debugging: Disable materials and only show light buffer.
        DebugMode = DeferredGraphicsDebugMode.VisualizeDiffuseLightBuffer
      };
      _graphicsScreen.DrawReticle = true;
      GraphicsService.Screens.Insert(0, _graphicsScreen);

      GameObjectService.Objects.Add(new DeferredGraphicsOptionsObject(Services));

      Services.Register(typeof(DebugRenderer), null, _graphicsScreen.DebugRenderer);
      Services.Register(typeof(IScene), null, _graphicsScreen.Scene);

      // Add gravity and damping to the physics simulation.
      Simulation.ForceEffects.Add(new Gravity());
      Simulation.ForceEffects.Add(new Damping());

      // Add a custom game object which controls the camera.
      var cameraGameObject = new CameraObject(Services);
      GameObjectService.Objects.Add(cameraGameObject);
      _graphicsScreen.ActiveCameraNode = cameraGameObject.CameraNode;

      GameObjectService.Objects.Add(new GrabObject(Services));

      // Create test scene.
      ShadowSample.CreateScene(Services, ContentManager, _graphicsScreen);

      // Create 3 different shadows:
      // The VarianceShadow covers the whole level.
      _vsmShadow = new VarianceShadow
      {
        Prefer16Bit = false,
        PreferredSize = 512,
        MinLightDistance = 200,
        MaxDistance = 200,
        FadeOutRange = 0,
        ShadowFog = 0,
        TargetArea = new Aabb(new Vector3F(-100, 0, -100), new Vector3F(100, 50, 100))
      };
      _vsmShadow.Filter = new Blur(GraphicsService);
      _vsmShadow.Filter.NumberOfPasses = 1;
      _vsmShadow.Filter.InitializeGaussianBlur(11, 3, false);

      // The CascadedShadow for static objects.
      _staticCascadedShadow = new CascadedShadow
      {
        PreferredSize = 1024,
        Prefer16Bit = true,
        Distances = new Vector4F(4, 12, 20, 80),
        MinLightDistance = 200,
      };

      // The CascadedShadow for dynamic objects covering a smaller distance.
      _dynamicCascadedShadow = new CascadedShadow
      {
        PreferredSize = 1024,
        Prefer16Bit = true,
        NumberOfCascades = 2,
        Distances = new Vector4F(4, 12, 0, 0),
        MinLightDistance = 200,
      };

      // Get directional light created by the DynamicSkyObject and replace the default
      // shadow with our a CompositeShadow.
      _lightNode = _graphicsScreen.Scene.GetDescendants().OfType<LightNode>().First(n => n.Shadow is CascadedShadow);
      _lightNode.Shadow = new CompositeShadow
      {
        Shadows =
        {
          _vsmShadow,
          _staticCascadedShadow,
          _dynamicCascadedShadow,
        }
      };

      // We do not want to render the same objects into all 3 shadow maps. We use a custom
      // render callback to render each objects into only one of the shadow maps.
      _graphicsScreen.ShadowMapRenderer.RenderCallback = context =>
      {
        // Query all shadow casters.
        var query = context.Scene.Query<ShadowCasterQuery>(context.CameraNode, context);
        if (query.ShadowCasters.Count == 0)
          return false;

        // Get the shadow which is currently being rendered.
        var shadow = context.Object;

        // Create a list of scene nodes for the current shadow.
        var list = _tempList;
        if (shadow == _vsmShadow)
        {
          // Get the hills and skyscrapers which have been marked with a user flag 
          // in ShadowSample.CreateScene.
          foreach (var node in query.ShadowCasters)
            if (node.UserFlags == 1)
              _tempList.Add(node);
        }
        else if (shadow == _staticCascadedShadow)
        {
          // Get all static objects except the hills/skyscrapers.
          foreach (var node in query.ShadowCasters)
            if (node.UserFlags == 0 && node.IsStatic)
              _tempList.Add(node);
        }
        else if (shadow == _dynamicCascadedShadow)
        {
          // Get all dynamic objects.
          foreach (var node in query.ShadowCasters)
            if (!node.IsStatic)
              _tempList.Add(node);
        }
        else
        {
          // Other shadows of other lights.
          list = query.ShadowCasters;
        }

        // Render the selected objects into the shadow map.
        _graphicsScreen.MeshRenderer.Render(list, context);

        _tempList.Clear();
        return true;
      };

      // Register the custom renderers for the VarianceShadow.
      _graphicsScreen.ShadowMapRenderer.Renderers.Add(new VarianceShadowMapRenderer(_graphicsScreen.ShadowMapRenderer.RenderCallback));
      _graphicsScreen.ShadowMaskRenderer.Renderers.Add(new VarianceShadowMaskRenderer(GraphicsService));

      CreateGuiControls();
    }
Пример #16
0
    // OnUnload() is called when the GameObject is removed from the IGameObjectService.
    protected override void OnUnload()
    {
      // Clean up.
      _campfire.Parent.Children.Remove(_campfire);
      _campfire.Dispose(false);
      _campfire = null;

      _fireParticles = null;
      _smokeParticles = null;
      _light = null;
      _random = null;
    }
Пример #17
0
        // OnLoad() is called when the GameObject is added to the IGameObjectService.
        protected override void OnLoad()
        {
            var content = _services.GetInstance<ContentManager>();
              _skyboxNode = new SkyboxNode(content.Load<TextureCube>("Sky2"))
              {
            Color = new Vector3F(SkyExposure),
              };

              // The ambient light.
              var ambientLight = new AmbientLight
              {
            Color = new Vector3F(0.9f, 0.9f, 1f),
            HdrScale = 0.1f,
            Intensity = 0.5f,
            HemisphericAttenuation = 0.8f,
              };
              _ambientLightNode = new LightNode(ambientLight)
              {
            Name = "Ambient",
              };

              // The main directional light.
              var sunlight = new DirectionalLight
              {
            Color = new Vector3F(1, 0.9607844f, 0.9078432f),
            HdrScale = 0.4f,
            DiffuseIntensity = 1,
            SpecularIntensity = 1,
              };
              _sunlightNode = new LightNode(sunlight)
              {
            Name = "Sunlight",
            Priority = 10,   // This is the most important light.
            PoseWorld = new Pose(QuaternionF.CreateRotationY(-1.4f) * QuaternionF.CreateRotationX(-0.6f)),

            // This light uses Cascaded Shadow Mapping.
            Shadow = new CascadedShadow
            {
            #if XBOX
              PreferredSize = 512,
            #else
              PreferredSize = 1024,
            #endif
              Prefer16Bit = true,
            }
              };

              // Add a lens flare for the key light.
              var lensFlare = new LensFlare(true) { QuerySize = 0.2f, Size = 0.2f, Name = "Sun Flare" };
              var lensFlareTexture = content.Load<Texture2D>("LensFlare/LensFlares");
              var circleTexture = new PackedTexture("Circle", lensFlareTexture, new Vector2F(0, 0), new Vector2F(0.25f, 0.5f));
              var glowTexture = new PackedTexture("Glow", lensFlareTexture, new Vector2F(0.25f, 0), new Vector2F(0.25f, 0.5f));
              var ringTexture = new PackedTexture("Ring", lensFlareTexture, new Vector2F(0.5f, 0), new Vector2F(0.25f, 0.5f));
              var haloTexture = new PackedTexture("Halo", lensFlareTexture, new Vector2F(0.75f, 0), new Vector2F(0.25f, 0.5f));
              var sunTexture = new PackedTexture("Sun", lensFlareTexture, new Vector2F(0, 0.5f), new Vector2F(0.25f, 0.5f));
              var streaksTexture = new PackedTexture("Streaks", lensFlareTexture, new Vector2F(0.25f, 0.5f), new Vector2F(0.25f, 0.5f));
              var flareTexture = new PackedTexture("Flare", lensFlareTexture, new Vector2F(0.5f, 0.5f), new Vector2F(0.25f, 0.5f));
              lensFlare.Elements.Add(new LensFlareElement(-0.2f, 0.55f, 0.0f, new Color(175, 175, 255, 20), new Vector2F(0.5f, 0.5f), circleTexture));
              lensFlare.Elements.Add(new LensFlareElement(0.0f, 0.9f, 0.0f, new Color(255, 255, 255, 255), new Vector2F(0.5f, 0.5f), sunTexture));
              lensFlare.Elements.Add(new LensFlareElement(0.0f, 1.8f, 0.0f, new Color(255, 255, 255, 128), new Vector2F(0.5f, 0.5f), streaksTexture));
              lensFlare.Elements.Add(new LensFlareElement(0.0f, 2.6f, 0.0f, new Color(255, 255, 200, 64), new Vector2F(0.5f, 0.5f), glowTexture));
              lensFlare.Elements.Add(new LensFlareElement(0.5f, 0.12f, 0.0f, new Color(60, 60, 180, 35), new Vector2F(0.5f, 0.5f), circleTexture));
              lensFlare.Elements.Add(new LensFlareElement(0.55f, 0.46f, 0.0f, new Color(100, 100, 200, 60), new Vector2F(0.5f, 0.5f), circleTexture));
              lensFlare.Elements.Add(new LensFlareElement(0.6f, 0.17f, 0.0f, new Color(120, 120, 220, 40), new Vector2F(0.5f, 0.5f), circleTexture));
              lensFlare.Elements.Add(new LensFlareElement(0.85f, 0.2f, 0.0f, new Color(60, 60, 255, 100), new Vector2F(0.5f, 0.5f), ringTexture));
              lensFlare.Elements.Add(new LensFlareElement(1.5f, 0.2f, 0.0f, new Color(255, 60, 60, 130), new Vector2F(0.5f, 0.5f), flareTexture));
              lensFlare.Elements.Add(new LensFlareElement(0.15f, 0.15f, 0.0f, new Color(255, 60, 60, 90), new Vector2F(0.5f, 0.5f), flareTexture));
              lensFlare.Elements.Add(new LensFlareElement(1.3f, 0.6f, 0.0f, new Color(60, 60, 255, 180), new Vector2F(0.5f, 0.5f), haloTexture));
              lensFlare.Elements.Add(new LensFlareElement(1.4f, 0.2f, 0.0f, new Color(220, 80, 80, 98), new Vector2F(0.5f, 0.5f), haloTexture));
              lensFlare.Elements.Add(new LensFlareElement(1.5f, 0.1f, 0.0f, new Color(220, 80, 80, 85), new Vector2F(0.5f, 0.5f), circleTexture));
              lensFlare.Elements.Add(new LensFlareElement(1.6f, 0.5f, 0.0f, new Color(60, 60, 255, 80), new Vector2F(0.5f, 0.5f), haloTexture));
              lensFlare.Elements.Add(new LensFlareElement(1.8f, 0.3f, 0.0f, new Color(90, 60, 255, 110), new Vector2F(0.5f, 0.5f), ringTexture));
              lensFlare.Elements.Add(new LensFlareElement(1.95f, 0.5f, 0.0f, new Color(60, 60, 255, 120), new Vector2F(0.5f, 0.5f), haloTexture));
              lensFlare.Elements.Add(new LensFlareElement(2.0f, 0.15f, 0.0f, new Color(60, 60, 255, 85), new Vector2F(0.5f, 0.5f), circleTexture));

              // Add lens flare as a child of the sunlight.
              var lensFlareNode = new LensFlareNode(lensFlare);
              _sunlightNode.Children = new SceneNodeCollection();
              _sunlightNode.Children.Add(lensFlareNode);

              // Add scene nodes to scene graph.
              var scene = _services.GetInstance<IScene>();
              scene.Children.Add(_skyboxNode);
              scene.Children.Add(_ambientLightNode);
              scene.Children.Add(_sunlightNode);
        }
Пример #18
0
        // OnUnload() is called when the GameObject is removed from the IGameObjectService.
        protected override void OnUnload()
        {
            _skyboxNode.Parent.Children.Remove(_skyboxNode);
              _skyboxNode.Dispose(false);
              _skyboxNode = null;

              _ambientLightNode.Parent.Children.Remove(_ambientLightNode);
              _ambientLightNode.Dispose(false);
              _ambientLightNode = null;

              _sunlightNode.Parent.Children.Remove(_sunlightNode);
              _sunlightNode.Dispose(false);
              _sunlightNode = null;
        }
Пример #19
0
        public static void AddLights(Scene scene)
        {
            if (scene == null)
                throw new ArgumentNullException(nameof(scene));

            float hdrScale = 1;

            // ----- Ambient light
            var ambientLight = new AmbientLight
            {
                Color = new Vector3F(0.05333332f, 0.09882354f, 0.1819608f),
                Intensity = 1,
                HemisphericAttenuation = 0,
                HdrScale = hdrScale,
            };
            scene.Children.Add(new LightNode(ambientLight));

            // ----- Key Light with shadow map
            var keyLight = new DirectionalLight
            {
                Color = new Vector3F(1, 0.9607844f, 0.8078432f),
                DiffuseIntensity = 1,
                SpecularIntensity = 1,
                HdrScale = hdrScale,
            };
            var keyLightNode = new LightNode(keyLight)
            {
                Name = "KeyLight",
                Priority = 10,   // This is the most important light.
                PoseWorld = new Pose(QuaternionF.CreateRotation(Vector3F.Forward, new Vector3F(-0.5265408f, -0.5735765f, -0.6275069f))),
                // This light uses Cascaded Shadow Mapping.
                Shadow = new CascadedShadow
                {
                    PreferredSize = 1024,
                    NumberOfCascades = 4,
                    Distances = new Vector4F(2, 4, 10, 20f),
                    MinLightDistance = 8,
                    FilterRadius = 2,
                    NumberOfSamples = 16,
                    CascadeSelection = ShadowCascadeSelection.BestDithered,
                }
            };
            scene.Children.Add(keyLightNode);

            // ----- Fill light
            var fillLight = new DirectionalLight
            {
                Color = new Vector3F(0.9647059f, 0.7607844f, 0.4078432f),
                DiffuseIntensity = 1,
                SpecularIntensity = 0,
                HdrScale = hdrScale,
            };
            var fillLightNode = new LightNode(fillLight)
            {
                Name = "FillLight",
                PoseWorld = new Pose(QuaternionF.CreateRotation(Vector3F.Forward, new Vector3F(0.7198464f, 0.3420201f, 0.6040227f))),
            };
            scene.Children.Add(fillLightNode);

            // ----- Back light
            var backLight = new DirectionalLight
            {
                Color = new Vector3F(0.3231373f, 0.3607844f, 0.3937255f),
                DiffuseIntensity = 1,
                SpecularIntensity = 1,
                HdrScale = hdrScale,
            };
            var backLightNode = new LightNode(backLight)
            {
                Name = "BackLight",
                PoseWorld = new Pose(QuaternionF.CreateRotation(Vector3F.Forward, new Vector3F(0.4545195f, -0.7660444f, 0.4545195f))),
            };
            scene.Children.Add(backLightNode);
        }
Пример #20
0
    public EnvironmentLightSample(Microsoft.Xna.Framework.Game game)
      : base(game)
    {
      SampleFramework.IsMouseVisible = false;

      _graphicsScreen = new DeferredGraphicsScreen(Services);
      _graphicsScreen.DrawReticle = true;
      GraphicsService.Screens.Insert(0, _graphicsScreen);
      GameObjectService.Objects.Add(new DeferredGraphicsOptionsObject(Services));

      Services.Register(typeof(DebugRenderer), null, _graphicsScreen.DebugRenderer);
      Services.Register(typeof(IScene), null, _graphicsScreen.Scene);

      // Add gravity and damping to the physics Simulation.
      Simulation.ForceEffects.Add(new Gravity());
      Simulation.ForceEffects.Add(new Damping());

      // Add a custom game object which controls the camera.
      var cameraGameObject = new CameraObject(Services);
      GameObjectService.Objects.Add(cameraGameObject);
      _graphicsScreen.ActiveCameraNode = cameraGameObject.CameraNode;

      GameObjectService.Objects.Add(new GrabObject(Services));
      GameObjectService.Objects.Add(new GroundObject(Services));
      GameObjectService.Objects.Add(new DudeObject(Services));
      var lavaBallsObject = new LavaBallsObject(Services);
      GameObjectService.Objects.Add(lavaBallsObject);
      GameObjectService.Objects.Add(new ObjectCreatorObject(Services));
      GameObjectService.Objects.Add(new FogObject(Services));
      GameObjectService.Objects.Add(new StaticObject(Services, "Barrier/Barrier", 0.9f, new Pose(new Vector3F(0, 0, -2))));
      GameObjectService.Objects.Add(new StaticObject(Services, "Barrier/Cylinder", 0.9f, new Pose(new Vector3F(3, 0, 0), QuaternionF.CreateRotationY(MathHelper.ToRadians(-20)))));
      GameObjectService.Objects.Add(new StaticSkyObject(Services));

      // Add a few palm trees.
      Random random = new Random(12345);
      for (int i = 0; i < 10; i++)
      {
        Vector3F position = new Vector3F(random.NextFloat(-3, -8), 0, random.NextFloat(0, -5));
        Matrix33F orientation = Matrix33F.CreateRotationY(random.NextFloat(0, ConstantsF.TwoPi));
        float scale = random.NextFloat(0.5f, 1.2f);
        GameObjectService.Objects.Add(new StaticObject(Services, "PalmTree/palm_tree", scale, new Pose(position, orientation)));
      }

      // Add some more dynamic objects.
      for (int i = 0; i < 5; i++)
      {
        lavaBallsObject.Spawn();
        GameObjectService.Objects.Add(new ProceduralObject(Services));
        GameObjectService.Objects.Add(new DynamicObject(Services, 7));
      }

      // To show the effect of the EnvironmentLight in isolation, disable all other light sources.
      //foreach (var light in _graphicsScreen.Scene.GetDescendants().OfType<LightNode>())
      //  light.IsEnabled = false;

      // Add the environment light.
      var environmentLight = new EnvironmentLight
      {
        Color = new Vector3F(0.1f),
        DiffuseIntensity = 0,
        SpecularIntensity = 1,
        EnvironmentMap = ContentManager.Load<TextureCube>("Sky2"),
      };
      var environmentLightNode = new LightNode(environmentLight)
      {
        Name = "Environment",
      };
      _graphicsScreen.Scene.Children.Add(environmentLightNode);

      // The EnvironmentLight is a new light type. We have to register a light renderer
      // for this light in the LightRenderer of the DeferredGraphicsScreen.
      _graphicsScreen.LightBufferRenderer.LightRenderer.Renderers.Add(new EnvironmentLightRenderer(GraphicsService));

      // EnvironmentLight.fx uses the specular power of the materials to determine
      // which mip map level of the cube is reflected. 
      // In reality, a high specular power is necessary to reflect the cube map
      // with all its detail. To reflect a cube map level with 512 texels size, we 
      // need a specular power of ~200000.
      // To make the reflection effects more obvious, let's change some material properties
      // and make the more reflective.

      // ProceduralObject:
      var proceduralObjects = _graphicsScreen.Scene
                                             .GetDescendants()
                                             .OfType<MeshNode>()
                                             .Where(mn => mn.Mesh.Name == "ProceduralObject")
                                             .Select(mn => mn.Mesh);
      foreach (var mesh in proceduralObjects)
      {
        foreach (var material in mesh.Materials)
        {
          material["GBuffer"].Set("SpecularPower", 10000f);
          material["Material"].Set("DiffuseColor", new Vector3(0.01f));
          material["Material"].Set("SpecularColor", new Vector3(1));
        }
      }

      // Frame of GlassBox:
      var glassBoxes = _graphicsScreen.Scene
                                      .GetDescendants()
                                      .OfType<ModelNode>()
                                      .Where(mn => mn.Name == "GlassBox")
                                      .Select(mn => ((MeshNode)mn.Children[0]).Mesh);
      foreach (var mesh in glassBoxes)
      {
        foreach (var material in mesh.Materials.Where(m => m.Contains("GBuffer")))
        {
          material["GBuffer"].Set("SpecularPower", 100000f);
          material["Material"].Set("DiffuseColor", new Vector3(0.0f));
          material["Material"].Set("SpecularColor", new Vector3(1));
        }
      }

      // LavaBall:
      var lavaBalls = _graphicsScreen.Scene
                                     .GetDescendants()
                                     .OfType<ModelNode>()
                                     .Where(mn => mn.Name == "LavaBall")
                                     .Select(mn => ((MeshNode)mn.Children[0]).Mesh);
      foreach (var mesh in lavaBalls)
      {
        foreach (var material in mesh.Materials.Where(m => m.Contains("GBuffer")))
        {
          material["GBuffer"].Set("SpecularPower", 10000f);
          material["Material"].Set("DiffuseColor", new Vector3(0.0f));
          material["Material"].Set("SpecularColor", new Vector3(10));
          material["Material"].Set("EmissiveColor", new Vector3(0.0f));
        }
      }

      // Ground plane:
      var groundPlanes = _graphicsScreen.Scene
                                        .GetDescendants()
                                        .OfType<ModelNode>()
                                        .Where(mn => mn.Name == "Ground")
                                        .Select(mn => ((MeshNode)mn.Children[0]).Mesh);
      foreach (var mesh in groundPlanes)
      {
        foreach (var material in mesh.Materials.Where(m => m.Contains("GBuffer")))
        {
          material["GBuffer"].Set("SpecularPower", 200000.0f);
          material["Material"].Set("DiffuseColor", new Vector3(0.5f));
          material["Material"].Set("SpecularColor", new Vector3(0.4f));
        }
      }

      // Please note, XNA does not filter cube maps over cube map borders. Therefore, reflections
      // of low resolution mip map levels might show obvious borders between the cube map
      // sides. In this case you can change the EnvironmentLight.fx effect to always reflect
      // the mip map level 0.
      // This is not a problem with MonoGame because DirectX automatically filters cube map borders.
    }
Пример #21
0
    // OnUnload() is called when the GameObject is removed from the IGameObjectService.
    protected override void OnUnload()
    {
      var scene = _ambientLightNode.Parent;

      scene.Children.Remove(_ambientLightNode);
      _ambientLightNode.Dispose(false);
      _ambientLightNode = null;

      scene.Children.Remove(_keyLightNode);
      _keyLightNode.Dispose(false);
      _keyLightNode = null;

      scene.Children.Remove(_fillLightNode);
      _fillLightNode.Dispose(false);
      _fillLightNode = null;

      scene.Children.Remove(_backLightNode);
      _backLightNode.Dispose(false);
      _backLightNode = null;
    }
Пример #22
0
        private int AssignShadowMask(LightNode lightNode, RenderContext context)
        {
            // Each shadow mask has 4 8-bit channels. We must assign a shadow mask channel to
              // each shadow-casting light. Non-overlapping lights can use the same channel.
              // Overlapping lights must use different channels. If we run out of channels,
              // we remove some lights from the list.

              var scene = context.Scene;

              var viewport = context.Viewport;
              int maskWidth = viewport.Width;
              int maskHeight = viewport.Height;
              if (UseHalfResolution && Numeric.IsLessOrEqual(UpsampleDepthSensitivity, 0))
              {
            // Half-res rendering with no upsampling.
            maskWidth /= 2;
            maskHeight /= 2;
              }

              // Loop over all bins until we find one which can be used for this light node.
              int binIndex;
              for (binIndex = 0; binIndex < _shadowMaskBins.Length; binIndex++)
              {
            var bin = _shadowMaskBins[binIndex];

            // Check if the light node touches any other light nodes in this bin.
            bool hasContact = false;
            foreach (var otherLightNode in bin)
            {
              if (scene.HaveContact(lightNode, otherLightNode))
              {
            hasContact = true;
            break;
              }
            }

            // No overlap. Use this bin.
            if (!hasContact)
            {
              bin.Add(lightNode);
              break;
            }
              }

              if (binIndex >= _shadowMaskBins.Length)
            return -1;  // Light node does not fit into any bin.

              int shadowMaskIndex = binIndex / 4;

              if (_shadowMasks[shadowMaskIndex] == null)
              {
            // Create shadow mask.
            var shadowMaskFormat = new RenderTargetFormat(maskWidth, maskHeight, false, SurfaceFormat.Color, DepthFormat.None);
            _shadowMasks[shadowMaskIndex] = context.GraphicsService.RenderTargetPool.Obtain2D(shadowMaskFormat);
              }

              // Assign shadow mask to light node.
              lightNode.Shadow.ShadowMask = _shadowMasks[shadowMaskIndex];
              lightNode.Shadow.ShadowMaskChannel = binIndex % 4;

              return shadowMaskIndex;
        }
Пример #23
0
    public ShadowSample(Microsoft.Xna.Framework.Game game)
      : base(game)
    {
      SampleFramework.IsMouseVisible = false;
      _graphicsScreen = new DeferredGraphicsScreen(Services)
      {
        // For debugging: Disable materials and only show light buffer.
        DebugMode = DeferredGraphicsDebugMode.VisualizeDiffuseLightBuffer
      };
      _graphicsScreen.DrawReticle = true;
      GraphicsService.Screens.Insert(0, _graphicsScreen);

      GameObjectService.Objects.Add(new DeferredGraphicsOptionsObject(Services));

      Services.Register(typeof(DebugRenderer), null, _graphicsScreen.DebugRenderer);
      Services.Register(typeof(IScene), null, _graphicsScreen.Scene);

      // Add gravity and damping to the physics simulation.
      Simulation.ForceEffects.Add(new Gravity());
      Simulation.ForceEffects.Add(new Damping());

      // Add a custom game object which controls the camera.
      var cameraGameObject = new CameraObject(Services);
      GameObjectService.Objects.Add(cameraGameObject);
      _graphicsScreen.ActiveCameraNode = cameraGameObject.CameraNode;

      GameObjectService.Objects.Add(new GrabObject(Services));

      CreateScene(Services, ContentManager, _graphicsScreen);

      // Disable existing lights.
      foreach (var lightNode in _graphicsScreen.Scene.GetDescendants().OfType<LightNode>())
        lightNode.IsEnabled = false;

      // Add a dim ambient light.
      _graphicsScreen.Scene.Children.Add(
        new LightNode(
          new AmbientLight
          {
            HemisphericAttenuation = 1,
            Intensity = 0.001f,
          }));

      // Add some test lights with shadows.
      _spotlight = new Spotlight { Range = 10, FalloffAngle = 0.8f, CutoffAngle = 1f };
      _standardShadow = new StandardShadow();
      _spotlightNode = new LightNode(_spotlight)
      {
        PoseWorld = new Pose(new Vector3F(0, 1f, -2)),
        Shadow = _standardShadow,
        IsEnabled = true,
      };
      _graphicsScreen.Scene.Children.Add(_spotlightNode);

      _cubeMapShadow = new CubeMapShadow();
      _pointLight = new PointLight { Range = 10, };
      _pointLightNode = new LightNode(_pointLight)
      {
        PoseWorld = new Pose(new Vector3F(0, 1f, -2)),
        Shadow = _cubeMapShadow,
        IsEnabled = false,
      };
      _graphicsScreen.Scene.Children.Add(_pointLightNode);

      CreateGuiControls();
    }
Пример #24
0
        private void AddNode(LightNode lightNode)
        {
            Debug.Assert(lightNode.ActualIsEnabled, "Scene query contains disabled nodes.");

            // Ignore light if the reference position is not in the clip geometry.
            if (lightNode.Clip != null && _referencePosition.HasValue)
            {
                bool haveContact = HaveContact(lightNode.Clip, _referencePosition.Value);

                if (lightNode.InvertClip == haveContact)
                {
                    return;
                }
            }

            // ----- Sort by estimated light contribution.

            // All lights except IBL will be sorted by contribution.
            // Note: If we have no reference node, it still makes sense to sort the objects
            // by their contribution. We choose to get the light contribution at the position
            // of each light.
            Vector3F position = _referencePosition ?? lightNode.PoseWorld.Position;

            //lightNode.SortTag = lightNode.GetLightContribution(position, 0.7f);

            // Or simpler: Sort light nodes by distance. --> Use for image-based lights.
            // (We use distance², because it is faster.)
            //float distance = (position - lightNode.PoseWorld.Position).LengthSquared;
            //lightNode.SortTag = -distance;   // minus because we use descending sort.

            if (lightNode.Light is AmbientLight)
            {
                AmbientLights.Add(lightNode);
                lightNode.SortTag = lightNode.GetLightContribution(position, 0.7f);
            }
            else if (lightNode.Light is DirectionalLight)
            {
                DirectionalLights.Add(lightNode);
                lightNode.SortTag = lightNode.GetLightContribution(position, 0.7f);
            }
            else if (lightNode.Light is PointLight)
            {
                PointLights.Add(lightNode);
                lightNode.SortTag = lightNode.GetLightContribution(position, 0.7f);
            }
            else if (lightNode.Light is Spotlight)
            {
                Spotlights.Add(lightNode);
                lightNode.SortTag = lightNode.GetLightContribution(position, 0.7f);
            }
            else if (lightNode.Light is ProjectorLight)
            {
                ProjectorLights.Add(lightNode);
                lightNode.SortTag = lightNode.GetLightContribution(position, 0.7f);
            }
            else if (lightNode.Light is ImageBasedLight)
            {
                ImageBasedLights.Add(lightNode);
                float distance = (position - lightNode.PoseWorld.Position).LengthSquared;
                lightNode.SortTag = -distance; // minus because we use descending sort.
            }
            else
            {
                OtherLights.Add(lightNode);
                lightNode.SortTag = lightNode.GetLightContribution(position, 0.7f);
            }
        }
Пример #25
0
    // OnLoad() is called when the GameObject is added to the IGameObjectService.
    protected override void OnLoad()
    {
      var particleSystemService = _services.GetInstance<IParticleSystemService>();

      // The campfire consists of two particle systems (fire + smoke) and a light source.
      // 
      //   _campfire (SceneNode)
      //      |
      //      +-- _fireParticles (ParticleSystemNode)
      //      |
      //      +-- _smokeParticles (ParticleSystemNode)
      //      |
      //      +-- _light (LightNode)

      // Use a basic scene node as the root node for the campfire.
      _campfire = new SceneNode
      {
        Name = "Campfire",
        PoseLocal = new Pose(new Vector3F(0, 0, -1)),
        Children = new SceneNodeCollection()
      };

      // Add fire particles.
      var contentManager = _services.GetInstance<ContentManager>();
      var particleSystem = CreateFire(contentManager);
      particleSystemService.ParticleSystems.Add(particleSystem);
      _fireParticles = new ParticleSystemNode(particleSystem)
      {
        // The fire effect lies in the xy plane and shoots into the forward direction (= -z axis).
        // Therefore we rotate the particle system to shoot upwards.
        PoseLocal = new Pose(new Vector3F(0, 0.2f, 0), Matrix33F.CreateRotationX(ConstantsF.PiOver2))
      };
      _campfire.Children.Add(_fireParticles);

      // Add smoke particles.
      particleSystem = CreateSmoke(contentManager);
      particleSystemService.ParticleSystems.Add(particleSystem);
      _smokeParticles = new ParticleSystemNode(particleSystem)
      {
        PoseLocal = new Pose(new Vector3F(0, 0.2f, 0), Matrix33F.CreateRotationX(ConstantsF.PiOver2))
      };
      _campfire.Children.Add(_smokeParticles);

      // Add a point light that illuminates the environment.
      var light = new PointLight
      {
        Attenuation = 0.1f,
        Color = new Vector3F(1, 0.2f, 0),
        HdrScale = 20,
        Range = 4
      };
      _light = new LightNode(light)
      {
        // Optional: We can make this light cast shadows - but this will cost performance!
        //Shadow = new CubeMapShadow { PreferredSize = 64, FilterRadius = 2, JitterResolution = 2048 },
        PoseLocal = new Pose(new Vector3F(0, 1f, 0))
      };
      _campfire.Children.Add(_light);

      // Add campfire to scene.
      var scene = _services.GetInstance<IScene>();
      scene.Children.Add(_campfire);

      // Particle effects can be added multiple times to the scene (= "instancing").
      // Uncomment the following lines to add a few more instance to the scene.
      //for (int i = 0; i < 10; i++)
      //{
      //  var clone = _campfire.Clone();

      //  // Set random scale, position, orientation.
      //  clone.ScaleLocal = _random.NextVector3F(0.5f, 1.5f);
      //  var pose = _campfire.PoseWorld;
      //  pose.Position.X += _random.NextFloat(-10, 10);
      //  pose.Position.Z += _random.NextFloat(-10, 10);
      //  pose.Orientation = Matrix33F.CreateRotationY(_random.NextFloat(-ConstantsF.PiOver2, ConstantsF.PiOver2));
      //  clone.PoseLocal = pose;

      //  scene.Children.Add(clone);
      //}

      // Add GUI controls to the Options window.
      var sampleFramework = _services.GetInstance<SampleFramework>();
      var optionsPanel = sampleFramework.AddOptions("Game Objects");
      var panel = SampleHelper.AddGroupBox(optionsPanel, "CampfireObject");
      SampleHelper.AddCheckBox(
        panel,
        "Enable campfire",
        IsEnabled,
        isChecked => IsEnabled = isChecked);
    }
Пример #26
0
    public ImageBasedLightingSample(Microsoft.Xna.Framework.Game game)
      : base(game)
    {
      SampleFramework.IsMouseVisible = false;

      _graphicsScreen = new DeferredGraphicsScreen(Services);
      _graphicsScreen.DrawReticle = true;
      GraphicsService.Screens.Insert(0, _graphicsScreen);
      GameObjectService.Objects.Add(new DeferredGraphicsOptionsObject(Services));

      Services.Register(typeof(DebugRenderer), null, _graphicsScreen.DebugRenderer);
      Services.Register(typeof(IScene), null, _graphicsScreen.Scene);

      // Add gravity and damping to the physics simulation.
      Simulation.ForceEffects.Add(new Gravity());
      Simulation.ForceEffects.Add(new Damping());

      // Add a custom game object which controls the camera.
      var cameraGameObject = new CameraObject(Services);
      GameObjectService.Objects.Add(cameraGameObject);
      _graphicsScreen.ActiveCameraNode = cameraGameObject.CameraNode;

      // Add standard game objects.
      GameObjectService.Objects.Add(new GrabObject(Services));
      GameObjectService.Objects.Add(new DynamicSkyObject(Services, true, false, true));
      GameObjectService.Objects.Add(new GroundObject(Services));
      GameObjectService.Objects.Add(new ObjectCreatorObject(Services));
      GameObjectService.Objects.Add(new DudeObject(Services) { Pose = new Pose(new Vector3F(-4, 0, 4)) });
      GameObjectService.Objects.Add(new LavaBallsObject(Services));

      // Create 3 image-based lights.
      for (int i = 0; i < 3; i++)
      {
        _imageBasedLights[i] = new ImageBasedLight
        {
          DiffuseIntensity = 1f,
          SpecularIntensity = 1f,
          FalloffRange = 0.2f,
          BlendMode = 1,    // 0 = add to ambient light, 1 = replace ambient light
        };
      }

      // The first IBL is infinite.
      _imageBasedLights[0].Shape = Shape.Infinite;

      // The other 2 IBLs have a box shape and use specify an AABB which is 
      // aligned to the with scene objects (walls, barrels, palm tree line).
      _imageBasedLights[1].Shape = new BoxShape(7.5f, 10, 7);
      _imageBasedLights[1].EnableLocalizedReflection = true;
      _imageBasedLights[1].LocalizedReflectionBox = new Aabb(new Vector3F(-100, -2, -100), new Vector3F(3.5f, 2, 100));

      _imageBasedLights[2].Shape = new BoxShape(7.5f, 10, 7);
      _imageBasedLights[2].EnableLocalizedReflection = true;
      _imageBasedLights[2].LocalizedReflectionBox = new Aabb(new Vector3F(-3, -2, -100), new Vector3F(3.5f, 2, 100));

      // Add 3 light nodes to add the IBL to the scene.
      for (int i = 0; i < 3; i++)
      {
        _lightNodes[i] = new LightNode(_imageBasedLights[i]);
        _graphicsScreen.Scene.Children.Add(_lightNodes[i]);
      }

      _lightNodes[0].PoseLocal = _globalRotation * new Pose(new Vector3F(-5, 5, 5));
      _lightNodes[1].PoseLocal = _globalRotation * new Pose(new Vector3F(0, 2, 0));
      _lightNodes[2].PoseLocal = _globalRotation * new Pose(new Vector3F(0, 2, -4));

      // Increase specular power of ground to create sharper reflections.
      var groundModelNode = (ModelNode)_graphicsScreen.Scene.GetSceneNode("Ground");
      var groundMaterial = ((MeshNode)groundModelNode.Children[0]).Mesh.Materials[0];
      groundMaterial["GBuffer"].Set("SpecularPower", 1000000.0f);

      // Add more test objects to the scenes.
      AddLightProbes();
      AddTestSpheres();
      AddTestObjects();

      CreateGuiControls();
    }