﻿// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.

HOWTO add more attributes to the particle vertices

1. Decide how the attribute will be generated. 
	If you need, you can add a new ParticleField by creating a new Initializer or Updater.
	You can also use existing particle fields.
	Finally, you can ignore all particle fields and use the same value for all attributes.
	
	Sample: Look at the InitialColorSeed.cs
	It requests a field to be added to the particles by
		RequiredFields.Add(ParticleFields.Color4);

	It then initializes the field for each new particle by calling:
		var colField = pool.GetField(ParticleFields.Color4);
		(*((Color4*)particle[colField])) = Color4.Lerp(ColorMin, ColorMax, randSeed.GetFloat(RandomOffset.Offset1A + SeedOffset));

	This ensures the particles now have a color field and each particle has some (random) value written in its field, but doesn't actually use the value yet.



2. Create a new VertexElement in ParticleVertexElements. Define proper name and type.

	Sample: We use
		public static VertexElement Color    = VertexElement.Color<Color>();

	for color. Or you can define your own name and pixel format, just like the random seed attribute does.



3. Change the shader code to use your new attribute. If the attribute can be dynamically added and removed,
	make it a compose mixin and provide base and derived classes for it.

	Sample: In ParticleBase.sdsl we define:
	    compose ParticleColor particleColor;
	    stage float4 Shading()
	    {
	        return ColorScale * particleColor.Compute();
	    }

	And the ParticleColor base class will return float4(1,1,1,1) when it's not defined, and streams.Color when it is (check the ParticleColorStream.sdsl for details)
	streams.Color gets its value from the COLOR semantic which we added in Step. 2


	
4. Decide where the attribute will get injected into the VertexBuffer - from the Material or from the ShapeBuilder (or both).
	In the Material/ShapeBuilder be sure to modify the PrepareForDraw(...) and UpdateVertexBuilder(...) methods and add the required VertexElement to the VertexBuilder.
	