예제 #1
0
    public SmokeSample(Microsoft.Xna.Framework.Game game)
      : base(game)
    {
      // Create a single particle system and add it multiple times to the scene 
      // graph ("instancing"). By default, all instances look identical. The 
      // properties ParticleSystemNode.Color/Alpha/AngleOffset can be used to 
      // render the particles with some variations.
      var particleSystem = Smoke.Create(ContentManager);
      ParticleSystemService.ParticleSystems.Add(particleSystem);

      _particleSystemNode0 = new ParticleSystemNode(particleSystem);
      GraphicsScreen.Scene.Children.Add(_particleSystemNode0);

      _particleSystemNode1 = new ParticleSystemNode(particleSystem);
      _particleSystemNode1.PoseWorld = new Pose(new Vector3F(5, 0, -5));
      _particleSystemNode1.Color = new Vector3F(0.9f, 0.8f, 0.7f);
      _particleSystemNode1.Alpha = 0.8f;
      _particleSystemNode1.AngleOffset = 0.3f;
      GraphicsScreen.Scene.Children.Add(_particleSystemNode1);

      _particleSystemNode2 = new ParticleSystemNode(particleSystem);
      _particleSystemNode2.PoseWorld = new Pose(new Vector3F(-10, 5, -5), Matrix33F.CreateRotationZ(-ConstantsF.PiOver2));
      _particleSystemNode2.Color = new Vector3F(0.5f, 0.5f, 0.5f);
      _particleSystemNode2.AngleOffset = 0.6f;
      GraphicsScreen.Scene.Children.Add(_particleSystemNode2);
    }
예제 #2
0
    public RibbonSample(Microsoft.Xna.Framework.Game game)
      : base(game)
    {
      GraphicsScreen.DrawReticle = true;

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

      // Load a sphere model.
      _modelNode = ContentManager.Load<ModelNode>("Particles/Sphere").Clone();
      GraphicsScreen.Scene.Children.Add(_modelNode);

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

      // Create a rigid body for the sphere.
      _rigidBody = new RigidBody(new SphereShape(0.5f))
      {
        Pose = new Pose(new Vector3F(-3, 0, 0)),
        LinearVelocity = new Vector3F(10, 10, -3f),
      };
      Simulation.RigidBodies.Add(_rigidBody);

      _particleSystem = RibbonEffect.Create(ContentManager);
      ParticleSystemService.ParticleSystems.Add(_particleSystem);
      _particleSystemNode = new ParticleSystemNode(_particleSystem);
      GraphicsScreen.Scene.Children.Add(_particleSystemNode);
    }
예제 #3
0
    public RingOfFireSample(Microsoft.Xna.Framework.Game game)
      : base(game)
    {
      // Create a new "empty" particle system.
      var particleSystem = new ParticleSystem();

      // Particle systems can have child particle systems. 
      // Add a fire and a smoke effect as children.
      var fire = Fire.Create(ContentManager);
      var smoke = Smoke.Create(ContentManager);  // The smoke effect from the previous sample.
      particleSystem.Children = new ParticleSystemCollection { fire, smoke };

      // If we need to, we can modify the predefined effects.
      // Change the smoke particle lifetime.
      smoke.Parameters.Get<float>(ParticleParameterNames.Lifetime).DefaultValue = 4;
      // Change the smoke's start positions to a ring.
      smoke.Effectors.OfType<StartPositionEffector>().First().Distribution =
        new CircleDistribution { InnerRadius = 2, OuterRadius = 2 };

      // Position the particle system (including its child) in the level.
      particleSystem.Pose = new Pose(new Vector3F(0, 3, 0));

      // We only need to add the parent particle system to the particle system service.
      // The service will automatically update the parent system each frame. The parent
      // system will automatically update its children.
      ParticleSystemService.ParticleSystems.Add(particleSystem);

      // Add the particle system to the scene graph.
      _particleSystemNode = new ParticleSystemNode(particleSystem);
      GraphicsScreen.Scene.Children.Add(_particleSystemNode);
    }
예제 #4
0
    public GrassSample(Microsoft.Xna.Framework.Game game)
      : base(game)
    {
      ParticleSystem particleSystem = Grass.Create(ContentManager);
      ParticleSystemService.ParticleSystems.Add(particleSystem);

      _particleSystemNode = new ParticleSystemNode(particleSystem);
      GraphicsScreen.Scene.Children.Add(_particleSystemNode);
    }
예제 #5
0
    public SuperEmitterSample(Microsoft.Xna.Framework.Game game)
      : base(game)
    {
      ParticleSystem particleSystem = new Rockets();
      ParticleSystemService.ParticleSystems.Add(particleSystem);

      _particleSystemNode = new ParticleSystemNode(particleSystem);
      GraphicsScreen.Scene.Children.Add(_particleSystemNode);
    }
예제 #6
0
    public DepthSortingSample(Microsoft.Xna.Framework.Game game)
      : base(game)
    {
      _brownOut = new BrownOut(ContentManager);
      ParticleSystemService.ParticleSystems.Add(_brownOut);

      _particleSystemNode = new ParticleSystemNode(_brownOut);
      GraphicsScreen.Scene.Children.Add(_particleSystemNode);
    }
예제 #7
0
    public FlameJetSample(Microsoft.Xna.Framework.Game game)
      : base(game)
    {
      _flameJet = FlameJet.Create(ContentManager);
      _flameJet.Pose = new Pose(new Vector3F(0, 2, 0), Matrix33F.CreateRotationY(ConstantsF.PiOver2));
      ParticleSystemService.ParticleSystems.Add(_flameJet);

      _particleSystemNode = new ParticleSystemNode(_flameJet);
      GraphicsScreen.Scene.Children.Add(_particleSystemNode);
    }
예제 #8
0
    public WaterFallSample(Microsoft.Xna.Framework.Game game)
      : base(game)
    {
      ParticleSystem particleSystem = WaterFall.CreateWaterFall(ContentManager);
      particleSystem.Pose = new Pose(new Vector3F(0, 2, 0), Matrix33F.CreateRotationY(ConstantsF.Pi));
      ParticleSystemService.ParticleSystems.Add(particleSystem);

      _particleSystemNode = new ParticleSystemNode(particleSystem);
      GraphicsScreen.Scene.Children.Add(_particleSystemNode);
    }
예제 #9
0
    public DecalSample(Microsoft.Xna.Framework.Game game)
      : base(game)
    {
      GraphicsScreen.DrawReticle = true;
      SetCamera(new Vector3F(0, 2, 6), 0, 0);

      _decals = Decals.Create(ContentManager);
      ParticleSystemService.ParticleSystems.Add(_decals);

      _particleSystemNode = new ParticleSystemNode(_decals);
      GraphicsScreen.Scene.Children.Add(_particleSystemNode);
    }
예제 #10
0
    public ExplosionSample(Microsoft.Xna.Framework.Game game)
      : base(game)
    {
      // Create an instance of the Explosion particle system.
      _explosion = new Explosion(ContentManager);
      _explosion.Pose = new Pose(new Vector3F(0, 5, 0));
      ParticleSystemService.ParticleSystems.Add(_explosion);

      _particleSystemNode = new ParticleSystemNode(_explosion);
      GraphicsScreen.Scene.Children.Add(_particleSystemNode);

      _explosionSound = ContentManager.Load<SoundEffect>("Particles/Explo1");
    }
예제 #11
0
    public VolumetricCloudSample(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));
      _dynamicSkyObject = new DynamicSkyObject(Services, false, false, true);
      GameObjectService.Objects.Add(_dynamicSkyObject);
      GameObjectService.Objects.Add(new GroundObject(Services));
      GameObjectService.Objects.Add(new ObjectCreatorObject(Services));
      GameObjectService.Objects.Add(new LavaBallsObject(Services));

      _particleCloud0 = new ParticleSystemNode(CreateParticleCloud(ContentManager))
      {
        PoseLocal = new Pose(new Vector3F(-0, 100, -400)),
      };
      ParticleSystemService.ParticleSystems.Add(_particleCloud0.ParticleSystem);
      _graphicsScreen.Scene.Children.Add(_particleCloud0);

      _particleCloud1 = new ParticleSystemNode(CreateParticleCloud(ContentManager))
      {
        PoseLocal = new Pose(new Vector3F(-200, 100, -200)),
      };
      ParticleSystemService.ParticleSystems.Add(_particleCloud1.ParticleSystem);
      _graphicsScreen.Scene.Children.Add(_particleCloud1);

      _particleCloud2 = new ParticleSystemNode(CreateParticleCloud(ContentManager))
      {
        PoseLocal = new Pose(new Vector3F(400, 400, -400)),
      };
      ParticleSystemService.ParticleSystems.Add(_particleCloud2.ParticleSystem);
      _graphicsScreen.Scene.Children.Add(_particleCloud2);
    }
예제 #12
0
    public AnimatedTextureSample(Microsoft.Xna.Framework.Game game)
      : base(game)
    {
      _beeSwarm = BeeSwarm.Create(ContentManager);
      _beeSwarm.Pose = new Pose(new Vector3F(0, 4, 0));

      // Create 100 bees.
      _beeSwarm.AddParticles(100);

      ParticleSystemService.ParticleSystems.Add(_beeSwarm);

      _particleSystemNode = new ParticleSystemNode(_beeSwarm);
      GraphicsScreen.Scene.Children.Add(_particleSystemNode);
    }
예제 #13
0
    public void Initialize(ContentManager contentManager)
    {
      if (ParticleSystemNode == null)
      {
        // This is the first time this instance is used.

        var ps = new ParticleSystem
        {
          Name = "Teleport" + _count,
          ReferenceFrame = ParticleReferenceFrame.Local,
          Children = new ParticleSystemCollection
          {
            CreateSparkles(contentManager),
            CreateFastBeams(contentManager),
            CreateSlowBeams(contentManager),
          }
        };

        // Add a uniform float particle parameter that contains the particle system time.
        ps.Parameters.AddUniform<float>("Time");
        ps.Effectors.Add(new TimeToSingleEffector { Parameter = "Time" });

        // Add a uniform GlobalAlpha parameter. This parameter controls the alpha of all
        // child particle systems. 
        ps.Parameters.AddUniform<float>("GlobalAlpha");
        ps.Effectors.Add(new SingleFadeEffector
        {
          ValueParameter = "GlobalAlpha",
          TimeParameter = "Time",
          FadeInStart = 0,
          FadeInEnd = 2,
          FadeOutStart = 2,
          FadeOutEnd = 3,
        });

        ParticleSystemValidator.Validate(ps);
        ParticleSystemValidator.Validate(ps.Children[0]);
        ParticleSystemValidator.Validate(ps.Children[1]);
        ParticleSystemValidator.Validate(ps.Children[2]);

        ParticleSystemNode = new ParticleSystemNode(ps) { Name = "TeleportNode" + _count };
        _count++;
      }
      else
      {
        ParticleSystem.Reset();
        ParticleSystemNode.PoseWorld = Pose.Identity;
      }
    }
예제 #14
0
    public CampfireSample(Microsoft.Xna.Framework.Game game)
      : base(game)
    {
      var particleSystem = Campfire.CreateCampfire(ContentManager);

      // Add a smoke effect as a child to the campfire.
      particleSystem.Children = new ParticleSystemCollection();
      particleSystem.Children.Add(CampfireSmoke.CreateCampfireSmoke(ContentManager));

      // Position the campfire (including its child) in the level.
      // (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.)
      particleSystem.Pose = new Pose(new Vector3F(0, 0.2f, 0), Matrix33F.CreateRotationX(ConstantsF.PiOver2));

      ParticleSystemService.ParticleSystems.Add(particleSystem);

      _particleSystemNode = new ParticleSystemNode(particleSystem);
      GraphicsScreen.Scene.Children.Add(_particleSystemNode);
    }
예제 #15
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);
    }
예제 #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
    public DistortionSample(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 StaticSkyObject(Services)); // Skybox + some lights.

      //GameObjectService.Objects.Add(new GroundObject(Services));
      // Add a ground plane with some detail to see the water refractions.
      Simulation.RigidBodies.Add(new RigidBody(new PlaneShape(new Vector3F(0, 1, 0), 0)));
      GameObjectService.Objects.Add(new StaticObject(Services, "Gravel/Gravel", 1, new Pose(new Vector3F(0, 0.001f, 0))));

      GameObjectService.Objects.Add(new DudeObject(Services));
      GameObjectService.Objects.Add(new DynamicObject(Services, 1));
      GameObjectService.Objects.Add(new DynamicObject(Services, 2));
      GameObjectService.Objects.Add(new DynamicObject(Services, 3));
      GameObjectService.Objects.Add(new DynamicObject(Services, 5));
      GameObjectService.Objects.Add(new DynamicObject(Services, 6));
      GameObjectService.Objects.Add(new DynamicObject(Services, 7));
      GameObjectService.Objects.Add(new ObjectCreatorObject(Services));
      GameObjectService.Objects.Add(new FogObject(Services));
      GameObjectService.Objects.Add(new CampfireObject(Services));
      GameObjectService.Objects.Add(new LavaBallsObject(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 DistortionFilter to post-processors.
      _distortionFilter = new DistortionFilter(GraphicsService, ContentManager);
      _graphicsScreen.PostProcessors.Add(_distortionFilter);

      // Add 3 particle systems. 
      // The ParticleSystems are added to the IParticleSystemService.
      // The ParticleSystemNodes are added to the Scene of the DistortionFilter - not the usual Scene!
      _fireDistortionParticleSystemNode = new ParticleSystemNode(CreateFireDistortionParticleSystem())
      {
        PoseLocal = new Pose(new Vector3F(0, 0f, -1), Matrix33F.CreateRotationX(ConstantsF.PiOver2)),
      };
      ParticleSystemService.ParticleSystems.Add(_fireDistortionParticleSystemNode.ParticleSystem);
      _distortionFilter.Scene.Children.Add(_fireDistortionParticleSystemNode);

      _explosionDistortionParticleSystemNode = new ParticleSystemNode(CreateExplosionDistortionParticleSystem())
      {
        PoseLocal = new Pose(new Vector3F(0, 0, -1)),
      };
      ParticleSystemService.ParticleSystems.Add(_explosionDistortionParticleSystemNode.ParticleSystem);
      _distortionFilter.Scene.Children.Add(_explosionDistortionParticleSystemNode);

      _novaDistortionParticleSystemNode = new ParticleSystemNode(CreateNovaDistortionParticleSystem())
      {
        PoseLocal = new Pose(new Vector3F(0, 0.5f, -1), Matrix33F.CreateRotationX(ConstantsF.PiOver2)),
      };
      ParticleSystemService.ParticleSystems.Add(_novaDistortionParticleSystemNode.ParticleSystem);
      _distortionFilter.Scene.Children.Add(_novaDistortionParticleSystemNode);
    }
예제 #18
0
    private void CreateParticleSystem()
    {
      // Load a sphere model.
      var modelNode = ContentManager.Load<ModelNode>("Particles/Sphere");
      var meshNode = (MeshNode)modelNode.Children[0];

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

      // Create two instances of the sphere model.
      _meshNode0 = meshNode.Clone();
      GraphicsScreen.Scene.Children.Add(_meshNode0);
      _meshNode1 = meshNode.Clone();
      GraphicsScreen.Scene.Children.Add(_meshNode1);

      // Create a rigid body for the left sphere.
      _rigidBody0 = new RigidBody(new SphereShape(0.5f))
      {
        Pose = new Pose(new Vector3F(-3, 4, 0)),
      };
      Simulation.RigidBodies.Add(_rigidBody0);

      // Create a rigid body for the right sphere. (Sharing the same shape, mass and material.)
      _rigidBody1 = new RigidBody(_rigidBody0.Shape, _rigidBody0.MassFrame, _rigidBody0.Material)
      {
        Pose = new Pose(new Vector3F(3, 4, 0)),
      };
      Simulation.RigidBodies.Add(_rigidBody1);

      // Extract basic triangle mesh from the sphere model.
      var triangleMesh = meshNode.Mesh.Submeshes[0].ToTriangleMesh();

      // Create a particle system for the left ball. This particle system uses
      // ReferenceFrame == ParticleReferenceFrame.World - which is the default for all 
      // particle systems. Particles are all relative to world space. The particle system pose 
      // determines the start positions and direction (when the StartPositionEffector and 
      // StartDirectionEffector are in use). Particles do not move with the particle system.
      _particleSystem0 = GlowingMeshEffect.Create(triangleMesh, ContentManager);
      _particleSystem0.ReferenceFrame = ParticleReferenceFrame.World;
      ParticleSystemService.ParticleSystems.Add(_particleSystem0);

      _particleSystemNode0 = new ParticleSystemNode(_particleSystem0);
      _meshNode0.Children = new SceneNodeCollection { _particleSystemNode0 };

      // Create a particle system for the right ball. This particle system uses
      // ReferenceFrame == ParticleReferenceFrame.Local. Particles are all relative to the 
      // particle system pose. Particles move with the particle system.
      _particleSystem1 = GlowingMeshEffect.Create(triangleMesh, ContentManager);
      _particleSystem1.ReferenceFrame = ParticleReferenceFrame.Local;
      ParticleSystemService.ParticleSystems.Add(_particleSystem1);

      _particleSystemNode1 = new ParticleSystemNode(_particleSystem1);
      _meshNode1.Children = new SceneNodeCollection { _particleSystemNode1 };
    }
예제 #19
0
    public BasicParticlesSample(Microsoft.Xna.Framework.Game game)
      : base(game)
    {
      // Create a new "empty" particle system.
      _particleSystem = new ParticleSystem();

      // Names are optional, but very useful for debugging.
      _particleSystem.Name = "MyFirstParticleSystem";

      // The particle system uses pre-allocated arrays. We should define an upper limit for
      // the number of particles that can be alive at the same moment.
      _particleSystem.MaxNumberOfParticles = 200;

      // The particle system's Pose defines the position and orientation of the particle system
      // in the world. 
      _particleSystem.Pose = new Pose(new Vector3F(0, 2, 0));

      // The properties of the particles in the particle system are defined using 
      // "particle parameters" (in the collection _particleSystem.Parameters).
      // Per default, there is only one parameter: "NormalizedAge" - which is managed
      // by the particle system itself and is the age of a particle in the range 0 - 1.

      // All our particles should live for 1 second after they have been created. Therefore,
      // we add a "uniform" parameter called "Lifetime" and set it to 1.
      var lifetimeParameter = _particleSystem.Parameters.AddUniform<float>("Lifetime");
      lifetimeParameter.DefaultValue = 1f;

      // Each particle should have a position value. Therefore, we add a "varying" parameter
      // called "Position". "Varying" means that each particle has its own position value.
      // The particle system will internally allocate a Vector3F array to store all particle
      // positions.
      _particleSystem.Parameters.AddVarying<Vector3F>("Position");

      // When particles are created, we want them to appear at random position in a spherical
      // volume. We add an effector which initializes the particle "Positions" of newly created
      // particles.
      _particleSystem.Effectors.Add(new StartPositionEffector
      {
        // This effector should initialize the "Position" parameter.
        // Parameter = "Position",     // "Position" is the default value anyway.

        // The start values should be chosen from this random value distribution:
        Distribution = new SphereDistribution { OuterRadius = 2 }
      });

      // The particles should slowly fade in and out to avoid sudden appearance and disappearance.
      // We add a varying particle parameter called "Alpha" to store the alpha value per particle.
      _particleSystem.Parameters.AddVarying<float>("Alpha");

      // The SingleFadeEffector animates a float parameter from 0 to a target value and
      // back to 0.
      _particleSystem.Effectors.Add(new SingleFadeEffector
      {
        // If TargetValueParameter is not set, then the target value is 1.
        //TargetValueParameter = 1,

        // The fade-in/out times are relative to a time parameter. 
        // By default the "NormalizedAge" of the particles is used.
        //TimeParameter = "NormalizedAge",

        // The Alpha value should be animated.
        ValueParameter = "Alpha",

        // The fade-in/out times relative to the normalized age.
        FadeInStart = 0.0f,
        FadeInEnd = 0.3f,
        FadeOutStart = 0.5f,
        FadeOutEnd = 1.0f,
      });

      // Next, we choose a texture for the particles. All particles use the same texture 
      // parameter, which means the parameter is "uniform".
      var textureParameter = _particleSystem.Parameters.AddUniform<Texture2D>("Texture");
      textureParameter.DefaultValue = ContentManager.Load<Texture2D>("Particles/LensFlare");

      // The blend mode is a value between 0 and 1, where 0 means additive blending
      // 1 means alpha blending. Values between 0 and 1 are allowed. The particles in
      // this example should be drawn using additive alpha blending. 
      var blendModeParameter = _particleSystem.Parameters.AddUniform<float>("BlendMode");
      blendModeParameter.DefaultValue = 0.0f;

      // There is a lot to configure. Did we forget anything? - We can use an optional helper method
      // to validate our particle system. Uninitialized or missing parameters are printed to the
      // Console. Check the Visual Studio Output window for any messages.
      ParticleSystemValidator.Validate(_particleSystem);

      // Adding the particle system to a ParticleSystemService is optional but very useful
      // because the service will update the particle system for us in each frame.
      ParticleSystemService.ParticleSystems.Add(_particleSystem);

      // To render the particle effect, we need to create a scene node and add it to the
      // scene graph.
      _particleSystemNode = new ParticleSystemNode(_particleSystem);
      GraphicsScreen.Scene.Children.Add(_particleSystemNode);

      // A tip for the future: 
      // The class ParticleParameterNames is a collection of strings that can be used for 
      // common particle parameters. It is recommended to use the particle parameter names in
      // this class to avoid problems because of typing errors in the source code.
    }