public static ParticleSystem Create(ContentManager contentManager) { var ps = new ParticleSystem { Name = "Grass", MaxNumberOfParticles = 400, }; // The grass particles do not die. ps.Parameters.AddUniform <float>(ParticleParameterNames.Lifetime).DefaultValue = float.PositiveInfinity; // We create all particles instantly. Up to 400 particles. Then the emission stops. ps.Effectors.Add(new StreamEmitter { DefaultEmissionRate = 400 * 60, EmissionLimit = 400, }); ps.Parameters.AddVarying <Vector3F>(ParticleParameterNames.Position); ps.Effectors.Add(new StartPositionEffector { Parameter = ParticleParameterNames.Position, Distribution = new BoxDistribution { MinValue = new Vector3F(-10, 0.4f, -10), MaxValue = new Vector3F(10, 0.4f, 10) } }); ps.Parameters.AddVarying <float>(ParticleParameterNames.SizeX); ps.Effectors.Add(new StartValueEffector <float> { Parameter = ParticleParameterNames.SizeX, Distribution = new UniformDistributionF(0.6f, 1), }); ps.Parameters.AddVarying <float>(ParticleParameterNames.SizeY); ps.Effectors.Add(new StartValueEffector <float> { Parameter = ParticleParameterNames.SizeY, Distribution = new UniformDistributionF(0.6f, 1), }); ps.Parameters.AddVarying <Vector3F>(ParticleParameterNames.Color); ps.Effectors.Add(new StartValueEffector <Vector3F> { Parameter = ParticleParameterNames.Color, Distribution = new LineSegmentDistribution { Start = new Vector3F(0.82f, 0.92f, 1) * 0.9f, End = new Vector3F(1, 1, 1) } }); ps.Parameters.AddUniform <Texture2D>(ParticleParameterNames.Texture).DefaultValue = contentManager.Load <Texture2D>("Particles/Grass"); ps.Parameters.AddUniform <BillboardOrientation>(ParticleParameterNames.BillboardOrientation).DefaultValue = BillboardOrientation.AxialViewPlaneAligned; ps.Parameters.AddUniform <bool>(ParticleParameterNames.IsDepthSorted).DefaultValue = true; ParticleSystemValidator.Validate(ps); return(ps); }
public static ParticleSystem Create(ContentManager contentManager) { var ps = new ParticleSystem { Name = "Ribbon", MaxNumberOfParticles = 50, }; // Ribbons are enabled by setting the "Type" to ParticleType.Ribbon. Consecutive // living particles are connected and rendered as ribbons (quad strips). At least // two living particles are required to create a ribbon. Dead particles // ("NormalizedAge" ≥ 1) can be used as delimiters to terminate one ribbon and // start the next ribbon. ps.Parameters.AddUniform <ParticleType>(ParticleParameterNames.Type).DefaultValue = ParticleType.Ribbon; ps.Parameters.AddUniform <float>(ParticleParameterNames.Lifetime).DefaultValue = 1; ps.Parameters.AddVarying <Vector3F>(ParticleParameterNames.Position); ps.Effectors.Add(new StartPositionEffector()); // The parameter "Axis" determines the orientation of the ribbon. // We could use a fixed orientation. It is also possible to "twist" the ribbon // by using a varying parameter. //ps.Parameters.AddUniform<Vector3F>(ParticleParameterNames.Axis).DefaultValue = // Vector3F.Up; ps.Effectors.Add(new RibbonEffector()); ps.Effectors.Add(new ReserveParticleEffector { Reserve = 1 }); ps.Parameters.AddUniform <float>(ParticleParameterNames.Size).DefaultValue = 1; ps.Parameters.AddVarying <Vector3F>(ParticleParameterNames.Color); ps.Effectors.Add(new StartValueEffector <Vector3F> { Parameter = ParticleParameterNames.Color, Distribution = new BoxDistribution { MinValue = new Vector3F(0.5f, 0.5f, 0.5f), MaxValue = new Vector3F(1, 1, 1) } }); ps.Parameters.AddVarying <float>(ParticleParameterNames.Alpha); ps.Effectors.Add(new FuncEffector <float, float> { InputParameter = ParticleParameterNames.NormalizedAge, OutputParameter = ParticleParameterNames.Alpha, Func = age => 6.7f * age * (1 - age) * (1 - age), }); ps.Parameters.AddUniform <Texture2D>(ParticleParameterNames.Texture).DefaultValue = contentManager.Load <Texture2D>("Particles/Ribbon"); // The parameter "TextureTiling" defines how the texture spreads across the ribbon. // 0 ... no tiling, // 1 ... repeat every particle, // n ... repeat every n-th particle ps.Parameters.AddUniform <int>(ParticleParameterNames.TextureTiling).DefaultValue = 1; ps.Parameters.AddUniform <float>(ParticleParameterNames.BlendMode).DefaultValue = 0; ParticleSystemValidator.Validate(ps); return(ps); }
public static ParticleSystem Create(ContentManager contentManager) { ParticleSystem ps = new ParticleSystem { Name = "Smoke", MaxNumberOfParticles = 200, }; // All particles should live for 5 seconds. ps.Parameters.AddUniform <float>(ParticleParameterNames.Lifetime).DefaultValue = 5; // Add an effector that emits particles at a constant rate. ps.Effectors.Add(new StreamEmitter { DefaultEmissionRate = 30, }); // The reference frame can be either "Local" or "World" (Default). // - "Local" means that the particle positions, directions, velocities, etc. // are relative to the ParticleSystemNode in the scene graph. // - "World" means that those values are given in world space. The position // of the ParticleSystemNode in the scene graph does not affect the particles. // (For more information check out sample "11-ReferenceFrame".) ps.ReferenceFrame = ParticleReferenceFrame.Local; // Particle positions start in the center of the particle system. ps.Parameters.AddVarying <Vector3F>(ParticleParameterNames.Position); ps.Effectors.Add(new StartPositionEffector { Parameter = ParticleParameterNames.Position, DefaultValue = Vector3F.Zero, }); // Particles move in the up direction with a random deviation of 0.5 radians and a // random speed. ps.Parameters.AddVarying <Vector3F>(ParticleParameterNames.Direction); ps.Effectors.Add(new StartDirectionEffector { Parameter = ParticleParameterNames.Direction, Distribution = new DirectionDistribution { Deviation = 0.5f, Direction = Vector3F.Up }, }); ps.Parameters.AddVarying <float>(ParticleParameterNames.LinearSpeed); ps.Effectors.Add(new StartValueEffector <float> { Parameter = ParticleParameterNames.LinearSpeed, Distribution = new UniformDistributionF(0.5f, 1), }); // The LinearVelocityEffector uses the Direction and LinearSpeed to update the Position // of particles. ps.Effectors.Add(new LinearVelocityEffector { // Following parameters are equal to the default values. No need to set them. //PositionParameter = ParticleParameterNames.Position, //DirectionParameter = ParticleParameterNames.Direction, //SpeedParameter = ParticleParameterNames.LinearSpeed, }); // To create a wind effect, we apply an acceleration to all particles. ps.Parameters.AddUniform <Vector3F>(ParticleParameterNames.LinearAcceleration).DefaultValue = new Vector3F(0.2f, -0.1f, 0); ps.Effectors.Add(new LinearAccelerationEffector { // Following parameters are equal to the default values. No need to set them. //AccelerationParameter = ParticleParameterNames.LinearAcceleration, //DirectionParameter = ParticleParameterNames.Direction, //SpeedParameter = ParticleParameterNames.LinearSpeed, }); // Each particle starts with a random rotation angle and a random angular speed. ps.Parameters.AddVarying <float>(ParticleParameterNames.Angle); ps.Effectors.Add(new StartValueEffector <float> { Parameter = ParticleParameterNames.Angle, Distribution = new UniformDistributionF(-ConstantsF.Pi, ConstantsF.Pi), }); ps.Parameters.AddVarying <float>(ParticleParameterNames.AngularSpeed); ps.Effectors.Add(new StartValueEffector <float> { Parameter = ParticleParameterNames.AngularSpeed, Distribution = new UniformDistributionF(-2, 2), }); // The AngularVelocityEffector uses the AngularSpeed to update the particle Angle. ps.Effectors.Add(new AngularVelocityEffector { // Following parameters are equal to the default values. No need to set them. //AngleParameter = ParticleParameterNames.Angle, //SpeedParameter = ParticleParameterNames.AngularSpeed, }); ps.Parameters.AddVarying <float>("StartSize"); ps.Effectors.Add(new StartValueEffector <float> { Parameter = "StartSize", Distribution = new UniformDistributionF(0.1f, 0.5f), }); ps.Parameters.AddVarying <float>("EndSize"); ps.Effectors.Add(new StartValueEffector <float> { Parameter = "EndSize", Distribution = new UniformDistributionF(2, 4), }); ps.Parameters.AddVarying <float>(ParticleParameterNames.Size); ps.Effectors.Add(new SingleLerpEffector { ValueParameter = ParticleParameterNames.Size, StartParameter = "StartSize", EndParameter = "EndSize", }); // Particle alpha fades in to a target value of 1 and then back out to 0. ps.Parameters.AddVarying <float>(ParticleParameterNames.Alpha); ps.Parameters.AddUniform <float>("TargetAlpha").DefaultValue = 1f; ps.Effectors.Add(new SingleFadeEffector { ValueParameter = ParticleParameterNames.Alpha, TargetValueParameter = "TargetAlpha", FadeInStart = 0f, FadeInEnd = 0.2f, FadeOutStart = 0.7f, FadeOutEnd = 1f, }); ps.Parameters.AddUniform <Texture2D>(ParticleParameterNames.Texture).DefaultValue = contentManager.Load <Texture2D>("Particles/Smoke"); ParticleSystemValidator.Validate(ps); return(ps); }
public static ParticleSystem Create(ContentManager contentManager) { var ps = new ParticleSystem { Name = "Rain", MaxNumberOfParticles = 2000, }; ps.Parameters.AddUniform <float>(ParticleParameterNames.Lifetime).DefaultValue = 0.8f; ps.Effectors.Add(new StreamEmitter { DefaultEmissionRate = 1200, }); ps.Parameters.AddVarying <Vector3F>(ParticleParameterNames.Position); ps.Effectors.Add(new StartPositionEffector { Parameter = ParticleParameterNames.Position, Distribution = new BoxDistribution { MinValue = new Vector3F(-20, 15, -20), MaxValue = new Vector3F(20, 15, 20) } }); ps.Parameters.AddVarying <Vector3F>(ParticleParameterNames.Direction); ps.Effectors.Add(new StartDirectionEffector { Parameter = ParticleParameterNames.Direction, Distribution = new DirectionDistribution { Deviation = 0f, Direction = -Vector3F.UnitY }, }); ps.Parameters.AddVarying <float>(ParticleParameterNames.LinearSpeed); ps.Effectors.Add(new StartValueEffector <float> { Parameter = ParticleParameterNames.LinearSpeed, Distribution = new UniformDistributionF(20, 30), }); ps.Effectors.Add(new LinearVelocityEffector()); ps.Parameters.AddUniform <float>(ParticleParameterNames.SizeX).DefaultValue = 0.03f; ps.Parameters.AddVarying <float>(ParticleParameterNames.SizeY); ps.Effectors.Add(new StartValueEffector <float> { Parameter = ParticleParameterNames.SizeY, Distribution = new UniformDistributionF(0.5f, 1.5f), }); ps.Parameters.AddUniform <Vector3F>(ParticleParameterNames.Color).DefaultValue = new Vector3F(0.5f, 0.7f, 0.9f); ps.Parameters.AddUniform <float>(ParticleParameterNames.Alpha).DefaultValue = 0.5f; ps.Parameters.AddUniform <Texture2D>(ParticleParameterNames.Texture).DefaultValue = contentManager.Load <Texture2D>("Particles/RainDrop"); // DigitalRune Graphics can render particles with different billboard orientations. // The rain drops should use axial billboards in the up direction (a.k.a. cylindrical // billboards). ps.Parameters.AddUniform <BillboardOrientation>(ParticleParameterNames.BillboardOrientation).DefaultValue = BillboardOrientation.AxialViewPlaneAligned; ps.Parameters.AddUniform <float>(ParticleParameterNames.BlendMode).DefaultValue = 0; ParticleSystemValidator.Validate(ps); return(ps); }
public static ParticleSystem CreateCampfireSmoke(ContentManager contentManager) { ParticleSystem ps = new ParticleSystem { Name = "CampfireSmoke", MaxNumberOfParticles = 50, }; // Each particle lives for a random time span. ps.Parameters.AddVarying <float>(ParticleParameterNames.Lifetime); ps.Effectors.Add(new StartValueEffector <float> { Parameter = ParticleParameterNames.Lifetime, Distribution = new UniformDistributionF(2.0f, 2.4f), }); // Add an effector that emits particles at a constant rate. ps.Effectors.Add(new StreamEmitter { DefaultEmissionRate = 15, }); // Particle positions start on a circular area (in the xy-plane). ps.Parameters.AddVarying <Vector3F>(ParticleParameterNames.Position); ps.Effectors.Add(new StartPositionEffector { Parameter = ParticleParameterNames.Position, Distribution = new CircleDistribution { OuterRadius = 0.4f, InnerRadius = 0 } }); // Particles move in forward direction with a slight random deviation with a random speed. ps.Parameters.AddVarying <Vector3F>(ParticleParameterNames.Direction); ps.Effectors.Add(new StartDirectionEffector { Parameter = ParticleParameterNames.Direction, Distribution = new DirectionDistribution { Deviation = 0.15f, Direction = Vector3F.Forward }, }); ps.Parameters.AddVarying <float>(ParticleParameterNames.LinearSpeed); ps.Effectors.Add(new StartValueEffector <float> { Parameter = ParticleParameterNames.LinearSpeed, Distribution = new UniformDistributionF(0, 1), }); // The LinearVelocityEffector uses the Direction and LinearSpeed to update the Position // of particles. ps.Effectors.Add(new LinearVelocityEffector()); // Lets apply a damping (= exponential decay) to the LinearSpeed using the SingleDampingEffector. ps.Parameters.AddUniform <float>(ParticleParameterNames.Damping).DefaultValue = 1.0f; ps.Effectors.Add(new SingleDampingEffector { // Following parameters are equal to the default values. No need to set them. //ValueParameter = ParticleParameterNames.LinearSpeed, //DampingParameter = ParticleParameterNames.Damping, }); // To create a wind effect, we apply an acceleration to all particles. ps.Parameters.AddUniform <Vector3F>("Wind").DefaultValue = new Vector3F(-1, 3, -0.5f); ps.Effectors.Add(new LinearAccelerationEffector { AccelerationParameter = "Wind" }); // Each particle starts with a random rotation angle and a random angular speed. ps.Parameters.AddVarying <float>(ParticleParameterNames.Angle); ps.Effectors.Add(new StartValueEffector <float> { Parameter = ParticleParameterNames.Angle, Distribution = new UniformDistributionF(-ConstantsF.PiOver2, ConstantsF.PiOver2), }); ps.Parameters.AddVarying <float>(ParticleParameterNames.AngularSpeed); ps.Effectors.Add(new StartValueEffector <float> { Parameter = ParticleParameterNames.AngularSpeed, Distribution = new UniformDistributionF(-2f, 2f), }); // The AngularVelocityEffector uses the AngularSpeed to update the particle Angle. ps.Effectors.Add(new AngularVelocityEffector { AngleParameter = ParticleParameterNames.Angle, SpeedParameter = ParticleParameterNames.AngularSpeed, }); // Each particle gets a random start and end size. ps.Parameters.AddVarying <float>("StartSize"); ps.Effectors.Add(new StartValueEffector <float> { Parameter = "StartSize", Distribution = new UniformDistributionF(0.5f, 0.7f), }); ps.Parameters.AddVarying <float>("EndSize"); ps.Effectors.Add(new StartValueEffector <float> { Parameter = "EndSize", Distribution = new UniformDistributionF(1.0f, 1.4f), }); // The Size is computed from linear interpolation between the StartSize and the EndSize. ps.Parameters.AddVarying <float>(ParticleParameterNames.Size); ps.Effectors.Add(new SingleLerpEffector { ValueParameter = ParticleParameterNames.Size, FactorParameter = ParticleParameterNames.NormalizedAge, StartParameter = "StartSize", EndParameter = "EndSize", }); // The Color slowly changes linearly from light gray to a darker gray. ps.Parameters.AddUniform <Vector3F>("StartColor").DefaultValue = new Vector3F(0.8f, 0.8f, 0.8f); ps.Parameters.AddUniform <Vector3F>("EndColor").DefaultValue = new Vector3F(0.3f, 0.3f, 0.3f); ps.Parameters.AddVarying <Vector3F>(ParticleParameterNames.Color); ps.Effectors.Add(new Vector3FLerpEffector { ValueParameter = ParticleParameterNames.Color, StartParameter = "StartColor", EndParameter = "EndColor", }); // The Alpha value is 0 for a short time, then it fades in to the TargetAlpha and finally // it fades out again. ps.Parameters.AddVarying <float>(ParticleParameterNames.Alpha); ps.Parameters.AddUniform <float>("TargetAlpha").DefaultValue = 0.33f; ps.Effectors.Add(new SingleFadeEffector { ValueParameter = ParticleParameterNames.Alpha, TargetValueParameter = "TargetAlpha", TimeParameter = ParticleParameterNames.NormalizedAge, FadeInStart = 0.36f, FadeInEnd = 0.6f, FadeOutStart = 0.6f, FadeOutEnd = 1.0f, }); // DigitalRune Graphics supports "texture atlases": The class PackedTexture // describes a single texture or tile set packed into a texture atlas. The // smoke texture in this example consists of 2 tiles. ps.Parameters.AddUniform <PackedTexture>(ParticleParameterNames.Texture).DefaultValue = new PackedTexture( "Smoke2", contentManager.Load <Texture2D>("Campfire/Smoke2"), Vector2F.Zero, Vector2F.One, 2, 1); // The particle parameter "AnimationTime" determines which tile is used, // where 0 = first tile, 1 = last tile. // --> Chooses a random tile for each particle when it is created. ps.Parameters.AddVarying <float>(ParticleParameterNames.AnimationTime); ps.Effectors.Add(new StartValueEffector <float> { Parameter = ParticleParameterNames.AnimationTime, Distribution = new UniformDistributionF(0, 1), }); // Smoke needs alpha blending. ps.Parameters.AddUniform <float>(ParticleParameterNames.BlendMode).DefaultValue = 1; ParticleSystemValidator.Validate(ps); return(ps); }
public static ParticleSystem Create(ITriangleMesh mesh, ContentManager contentManager) { var ps = new ParticleSystem { Name = "GlowingMeshEffect", MaxNumberOfParticles = 100 }; ps.Parameters.AddUniform <float>(ParticleParameterNames.Lifetime).DefaultValue = 1.0f; ps.Effectors.Add(new StreamEmitter { DefaultEmissionRate = 100, }); // The particles start on random positions on the surface of the given triangle mesh. ps.Parameters.AddVarying <Vector3F>(ParticleParameterNames.Position); ps.Effectors.Add(new StartOnMeshEffector { Parameter = ParticleParameterNames.Position, Mesh = mesh }); // Just to demonstrate a new custom effector: // The size follows a user-defined curve using the FuncEffector. ps.Parameters.AddVarying <float>(ParticleParameterNames.Size); ps.Effectors.Add(new FuncEffector <float, float> { InputParameter = ParticleParameterNames.NormalizedAge, OutputParameter = ParticleParameterNames.Size, Func = age => 6.7f * age * (1 - age) * (1 - age) * 0.4f, }); ps.Parameters.AddVarying <Vector3F>(ParticleParameterNames.Color); ps.Effectors.Add(new StartValueEffector <Vector3F> { Parameter = ParticleParameterNames.Color, Distribution = new BoxDistribution { MinValue = new Vector3F(0.5f, 0.5f, 0.5f), MaxValue = new Vector3F(1, 1, 1) } }); ps.Parameters.AddVarying <float>(ParticleParameterNames.Alpha); ps.Effectors.Add(new FuncEffector <float, float> { InputParameter = ParticleParameterNames.NormalizedAge, OutputParameter = ParticleParameterNames.Alpha, Func = age => 6.7f * age * (1 - age) * (1 - age), }); ps.Parameters.AddUniform <Texture2D>(ParticleParameterNames.Texture).DefaultValue = contentManager.Load <Texture2D>("Particles/Star"); ps.Parameters.AddUniform <float>(ParticleParameterNames.BlendMode).DefaultValue = 0; ps.Parameters.AddUniform <BillboardOrientation>(ParticleParameterNames.BillboardOrientation).DefaultValue = BillboardOrientation.ScreenAligned; ParticleSystemValidator.Validate(ps); return(ps); }
public static ParticleSystem Create(ContentManager contentManager) { var ps = new ParticleSystem { Name = "BeeSwarm", MaxNumberOfParticles = 100, }; ps.Parameters.AddUniform <float>(ParticleParameterNames.Lifetime).DefaultValue = float.PositiveInfinity; ps.Parameters.AddVarying <Vector3F>(ParticleParameterNames.Position); ps.Effectors.Add(new StartPositionEffector { Parameter = ParticleParameterNames.Position, DefaultValue = new Vector3F(0, 0, 0) }); ps.Parameters.AddUniform <float>(ParticleParameterNames.SizeY).DefaultValue = 0.1f; // The SizeX is varying because the BeeEffector sets a negative size if the bee should look in the // opposite direction. ps.Parameters.AddVarying <float>(ParticleParameterNames.SizeX); ps.Effectors.Add(new StartValueEffector <float> { Parameter = ParticleParameterNames.SizeX, DefaultValue = 0.1f, }); ps.Parameters.AddVarying <float>(ParticleParameterNames.LinearSpeed); ps.Effectors.Add(new StartValueEffector <float> { Parameter = ParticleParameterNames.LinearSpeed, Distribution = new UniformDistributionF(1, 2), }); // The BeeEffector creates the random movement of the bees. ps.Parameters.AddVarying <Vector3F>("TargetPosition"); ps.Parameters.AddUniform <Pose>("CameraPose").DefaultValue = Pose.Identity; ps.Effectors.Add(new BeeEffector { PositionParameter = ParticleParameterNames.Position, TargetPositionParameter = "TargetPosition", SpeedParameter = ParticleParameterNames.LinearSpeed, SizeXParameter = ParticleParameterNames.SizeX, CameraPoseParameter = "CameraPose", InvertLookDirection = true, MaxRange = 4.0f, }); // The texture is a set of 3 images. ps.Parameters.AddUniform <PackedTexture>(ParticleParameterNames.Texture).DefaultValue = new PackedTexture( "Bee", contentManager.Load <Texture2D>("Particles/beeWingFlap"), Vector2F.Zero, Vector2F.One, 3, 1); // The Frame particle parameter stores the index of the animation frame and the // AnimationTime particle parameter stores the current progress in seconds. ps.Parameters.AddVarying <int>("Frame"); ps.Parameters.AddVarying <float>("AnimationTime"); // Initialize the AnimationTime with a random value, otherwise all bees would look // the same. ps.Effectors.Add(new StartValueEffector <float> { Parameter = "AnimationTime", Distribution = new UniformDistributionF(0, 0.125f), }); // The AnimationEffector advances the AnimationTime and sets the Frame. // It changes frames at 24 fps. ps.Effectors.Add(new AnimationEffector { AnimationTimeParameter = "AnimationTime", FramesPerSecond = 24, NumberOfFrames = 3, }); ParticleSystemValidator.Validate(ps); return(ps); }
private RocketTrail(ContentManager contentManager) { MaxNumberOfParticles = 200; Parameters.AddVarying <float>(ParticleParameterNames.Lifetime); Effectors.Add(new StartValueEffector <float> { Parameter = ParticleParameterNames.Lifetime, Distribution = new UniformDistributionF(1, 2), }); Parameters.AddUniform <float>(ParticleParameterNames.EmissionRate); Effectors.Add(new StartValueEffector <float> { Parameter = ParticleParameterNames.EmissionRate, DefaultValue = 60, }); Effectors.Add(new StreamEmitter { EmissionRateParameter = ParticleParameterNames.EmissionRate, }); Parameters.AddVarying <Vector3F>(ParticleParameterNames.Position); Effectors.Add(new StartPositionEffector { Parameter = ParticleParameterNames.Position, }); Parameters.AddVarying <Vector3F>(ParticleParameterNames.Direction); Effectors.Add(new StartDirectionEffector { Parameter = ParticleParameterNames.Direction, Distribution = new DirectionDistribution { Deviation = ConstantsF.Pi, Direction = Vector3F.UnitY }, }); Parameters.AddVarying <float>(ParticleParameterNames.LinearSpeed); Effectors.Add(new StartValueEffector <float> { Parameter = ParticleParameterNames.LinearSpeed, Distribution = new UniformDistributionF(0.1f, 0.3f), }); // The StartVelocityBiasEffector adds a velocity to new particles. We use this to add // the rocket velocity (stored in the parameter "EmitterVelocity") to the start velocities // of the particles. Parameters.AddUniform <Vector3F>(ParticleParameterNames.EmitterVelocity); Effectors.Add(new StartVelocityBiasEffector { Strength = 0.1f }); Effectors.Add(new LinearVelocityEffector()); Parameters.AddVarying <float>(ParticleParameterNames.Angle); Effectors.Add(new StartValueEffector <float> { Parameter = ParticleParameterNames.Angle, Distribution = new UniformDistributionF(-ConstantsF.Pi, ConstantsF.Pi), }); Parameters.AddVarying <float>(ParticleParameterNames.AngularSpeed); Effectors.Add(new StartValueEffector <float> { Parameter = ParticleParameterNames.AngularSpeed, Distribution = new UniformDistributionF(-1, 1), }); Effectors.Add(new AngularVelocityEffector()); Parameters.AddVarying <float>("StartSize"); Effectors.Add(new StartValueEffector <float> { Parameter = "StartSize", Distribution = new UniformDistributionF(0.2f, 0.5f), }); Parameters.AddVarying <float>("EndSize"); Effectors.Add(new StartValueEffector <float> { Parameter = "EndSize", Distribution = new UniformDistributionF(0.5f, 1f), }); Parameters.AddVarying <float>(ParticleParameterNames.Size); Effectors.Add(new SingleLerpEffector { ValueParameter = ParticleParameterNames.Size, StartParameter = "StartSize", EndParameter = "EndSize", }); Parameters.AddVarying <Vector3F>(ParticleParameterNames.Color); Effectors.Add(new StartValueEffector <Vector3F> { Parameter = ParticleParameterNames.Color, Distribution = new LineSegmentDistribution { Start = new Vector3F(0.5f, 0.4f, 0.25f), End = new Vector3F(0.7f, 0.6f, 0.5f) }, }); Parameters.AddVarying <float>(ParticleParameterNames.Alpha); Effectors.Add(new FuncEffector <float, float> { InputParameter = ParticleParameterNames.NormalizedAge, OutputParameter = ParticleParameterNames.Alpha, Func = age => 6.7f * age * (1 - age) * (1 - age), }); Parameters.AddUniform <Texture2D>(ParticleParameterNames.Texture).DefaultValue = contentManager.Load <Texture2D>("Particles/Smoke"); // Draw behind explosion. Parameters.AddUniform <int>(ParticleParameterNames.DrawOrder).DefaultValue = -100; // The ParticleSystemRecycler recycles this instance into the specified resource // pool when all particles are dead. Effectors.Add(new ParticleSystemRecycler { ResourcePool = Pool, // Set a minimum life-time to avoid that the particle system is recycled too early. // (The rocket trail might need a few frames before particles are created.) MinRuntime = TimeSpan.FromSeconds(0.05f), }); ParticleSystemValidator.Validate(this); }
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. }
public static ParticleSystem CreateCampfire(ContentManager contentManager) { ParticleSystem ps = new ParticleSystem { Name = "Campfire", MaxNumberOfParticles = 50 }; // Each particle lives for a random time span. ps.Parameters.AddVarying <float>(ParticleParameterNames.Lifetime); ps.Effectors.Add(new StartValueEffector <float> { Parameter = ParticleParameterNames.Lifetime, Distribution = new UniformDistributionF(0.8f, 1.2f), }); // Add an effector that emits particles at a constant rate. ps.Effectors.Add(new StreamEmitter { DefaultEmissionRate = 30, }); // Particle positions start on a circular area (in the xy-plane). ps.Parameters.AddVarying <Vector3F>(ParticleParameterNames.Position); ps.Effectors.Add(new StartPositionEffector { Parameter = ParticleParameterNames.Position, Distribution = new CircleDistribution { OuterRadius = 0.4f, InnerRadius = 0 } }); // Particles move in forward direction with a random speed. ps.Parameters.AddUniform <Vector3F>(ParticleParameterNames.Direction).DefaultValue = Vector3F.Forward; ps.Parameters.AddVarying <float>(ParticleParameterNames.LinearSpeed); ps.Effectors.Add(new StartValueEffector <float> { Parameter = ParticleParameterNames.LinearSpeed, Distribution = new UniformDistributionF(0, 1), }); // The LinearVelocityEffector uses the Direction and LinearSpeed to update the Position // of particles. ps.Effectors.Add(new LinearVelocityEffector()); // Lets apply a damping (= exponential decay) to the LinearSpeed using the SingleDampingEffector. ps.Parameters.AddUniform <float>(ParticleParameterNames.Damping).DefaultValue = 1.0f; ps.Effectors.Add(new SingleDampingEffector { // Following parameters are equal to the default values. No need to set them. //ValueParameter = ParticleParameterNames.LinearSpeed, //DampingParameter = ParticleParameterNames.Damping, }); // To create a wind effect, we apply an acceleration to all particles. ps.Parameters.AddUniform <Vector3F>("Wind").DefaultValue = new Vector3F(-1, 3, -0.5f); ps.Effectors.Add(new LinearAccelerationEffector { AccelerationParameter = "Wind" }); // Each particle starts with a random rotation angle and a random angular speed. ps.Parameters.AddVarying <float>(ParticleParameterNames.Angle); ps.Effectors.Add(new StartValueEffector <float> { Parameter = ParticleParameterNames.Angle, Distribution = new UniformDistributionF(-ConstantsF.Pi, ConstantsF.Pi), }); ps.Parameters.AddVarying <float>(ParticleParameterNames.AngularSpeed); ps.Effectors.Add(new StartValueEffector <float> { Parameter = ParticleParameterNames.AngularSpeed, Distribution = new UniformDistributionF(-2f, 2f), }); // The AngularVelocityEffector uses the AngularSpeed to update the particle Angle. ps.Effectors.Add(new AngularVelocityEffector()); // All particle have the same size. ps.Parameters.AddUniform <float>(ParticleParameterNames.Size).DefaultValue = 0.8f; // Particle alpha fades in to 1 and then back out to 0. ps.Parameters.AddVarying <float>(ParticleParameterNames.Alpha); ps.Effectors.Add(new SingleFadeEffector { ValueParameter = ParticleParameterNames.Alpha, FadeInStart = 0.0f, FadeInEnd = 0.2f, FadeOutStart = 0.8f, FadeOutEnd = 1.0f, }); // DigitalRune Graphics supports "texture atlases": The class PackedTexture // describes a single texture or tile set packed into a texture atlas. The // fire texture in this example consists of 4 tiles. ps.Parameters.AddUniform <PackedTexture>(ParticleParameterNames.Texture).DefaultValue = new PackedTexture( "FireParticles", contentManager.Load <Texture2D>("Campfire/FireParticles"), Vector2F.Zero, Vector2F.One, 4, 1); // The particle parameter "AnimationTime" determines which tile is used, // where 0 = first tile, 1 = last tile. // --> Chooses a random tile for each particle when it is created. ps.Parameters.AddVarying <float>(ParticleParameterNames.AnimationTime); ps.Effectors.Add(new StartValueEffector <float> { Parameter = ParticleParameterNames.AnimationTime, Distribution = new UniformDistributionF(0, 1), }); // Fire needs additive blending. ps.Parameters.AddUniform <float>(ParticleParameterNames.BlendMode).DefaultValue = 0; ParticleSystemValidator.Validate(ps); return(ps); }
public static ParticleSystem Create(ContentManager contentManager) { ParticleSystem ps = new ParticleSystem { Name = "Fire", MaxNumberOfParticles = 300 }; ps.Parameters.AddUniform <float>(ParticleParameterNames.Lifetime).DefaultValue = 2; ps.Effectors.Add(new StreamEmitter { DefaultEmissionRate = 120, }); ps.Parameters.AddVarying <Vector3F>(ParticleParameterNames.Position); ps.Effectors.Add(new StartPositionEffector { Parameter = ParticleParameterNames.Position, Distribution = new CircleDistribution { OuterRadius = 2, InnerRadius = 2 } }); ps.Parameters.AddVarying <Vector3F>(ParticleParameterNames.Direction); ps.Effectors.Add(new StartDirectionEffector { Parameter = ParticleParameterNames.Direction, // The start direction can be any direction (direction deviation is 360°). Distribution = new DirectionDistribution { Deviation = ConstantsF.TwoPi, Direction = Vector3F.UnitY }, }); ps.Parameters.AddVarying <float>(ParticleParameterNames.LinearSpeed); ps.Effectors.Add(new StartValueEffector <float> { Parameter = ParticleParameterNames.LinearSpeed, Distribution = new UniformDistributionF(0, 0.5f), }); ps.Effectors.Add(new LinearVelocityEffector()); ps.Parameters.AddUniform <Vector3F>(ParticleParameterNames.LinearAcceleration).DefaultValue = new Vector3F(0, 1, 0); ps.Effectors.Add(new LinearAccelerationEffector()); ps.Parameters.AddVarying <float>(ParticleParameterNames.Angle); ps.Effectors.Add(new StartValueEffector <float> { Parameter = ParticleParameterNames.Angle, Distribution = new UniformDistributionF(-ConstantsF.Pi, ConstantsF.Pi), }); ps.Parameters.AddUniform <float>("TargetAlpha").DefaultValue = 1f; ps.Parameters.AddVarying <float>(ParticleParameterNames.Alpha); ps.Effectors.Add(new SingleFadeEffector { ValueParameter = ParticleParameterNames.Alpha, TargetValueParameter = "TargetAlpha", FadeInStart = 0f, FadeInEnd = 0.1f, FadeOutStart = 0.2f, FadeOutEnd = 1f, }); ps.Parameters.AddVarying <float>(ParticleParameterNames.Size); ps.Effectors.Add(new StartValueEffector <float> { Parameter = ParticleParameterNames.Size, Distribution = new UniformDistributionF(0.5f, 1), }); ps.Parameters.AddUniform <Texture2D>(ParticleParameterNames.Texture).DefaultValue = contentManager.Load <Texture2D>("Particles/Fire"); // Fire needs additive blending. ps.Parameters.AddUniform <float>(ParticleParameterNames.BlendMode).DefaultValue = 0.0f; // Fire should be drawn on top of other effects (like smoke). // "DrawOrder" is supported by the ParticleBatch renderer. ps.Parameters.AddUniform <int>(ParticleParameterNames.DrawOrder).DefaultValue = 100; ParticleSystemValidator.Validate(ps); return(ps); }