How to particle system. A link to MrGrak's small github cpu particle example.

the updated shader.

//_________________________________________________________________
//_______________________ InstancingShader ___________________________
//_________________________________________________________________


// the shader model well use for dx or gl
#if OPENGL
#define SV_POSITION POSITION
#define VS_SHADERMODEL vs_3_0
#define PS_SHADERMODEL ps_3_0
#else
#define VS_SHADERMODEL vs_4_0
#define PS_SHADERMODEL ps_4_0
#endif



//______________________________________
// shader constants.
//______________________________________


static const float PI = 3.14159;
static const float PI2 = 6.28318;
static const float EIGHT_PI = 25.13274;



//______________________________________
// shader variables.
// we set these up in game1.
//______________________________________


matrix World, View, Projection;

float TotalTime;


//______________________________________
// the shader textures and samplers.
// we set the texture to use thru game1
//______________________________________


Texture2D ParticleTexture;
sampler2D TexSampler = sampler_state
{
	Texture = <ParticleTexture>;
	//AddressU = Wrap;//AddressV = Wrap;//MinFilter = Anisotropic;//MagFilter = Anisotropic;//MipFilter = Point;
};




//______________________________________
// the shader structs well be defining.
// these match the vertex definitions in game1.
//______________________________________


struct VSInstanceInputSimple
{
	float3 InstancePosition : POSITION1; // the number used must match the vertex declaration.
	float4 InstanceColor : COLOR1;
};

struct VSVertexInputSimple
{
	float4 Position : POSITION0;
	float2 TexCoord : TEXCOORD0;
};

struct VSOutputSimple
{
	float4 Position : SV_POSITION;
	float2 TexCoord : TEXCOORD0;
	float4 IdColor : COLOR0;
};




//______________________________________
// the vertex shaders.
//______________________________________


VSOutputSimple VertexShader01(in VSVertexInputSimple vertexInput, VSInstanceInputSimple instanceInput)
{
	VSOutputSimple output;
    
    float4x4 vp = mul(View, Projection);
    float4x4 wvp = mul(World, vp);
    float4 posVert = mul(vertexInput.Position, wvp);
    float4 posInst = mul(instanceInput.InstancePosition.xyz, wvp);
    float4 pos = (posVert + posInst);
    output.Position = pos;
    output.IdColor = instanceInput.InstanceColor;
	output.TexCoord = vertexInput.TexCoord;

	return output;
}

VSOutputSimple VertexShader02(in VSVertexInputSimple vertexInput, VSInstanceInputSimple instanceInput)
{
    VSOutputSimple output;
    
    float4x4 vp = mul(View, Projection);
    float4x4 wvp = mul(World, vp);
    float4 vert = vertexInput.Position;
    vert.xy *= (instanceInput.InstanceColor.a + 0.2f) * 50.0f; //10.0f; scalar
    float4 posVert = mul(vert, wvp);
    float4 posInst = mul(instanceInput.InstancePosition.xyz, wvp);
    float4 pos = (posVert + posInst);
    output.Position = pos;
    output.IdColor = instanceInput.InstanceColor;
    output.TexCoord = vertexInput.TexCoord;

    return output;
}



//______________________________________
// the pixel shaders.
//______________________________________


float4 PixelShader01(VSOutputSimple input) : COLOR0
{
    float4 col = tex2D(TexSampler, input.TexCoord);
    float alpha = col.a * (1.0f - input.IdColor.a);
    float3 blendedColor = col.rgb * input.IdColor.rgb * (alpha * 1.4f);
    return float4(blendedColor, alpha);
}



//______________________________________
// the techniques.
// we set this from game1.
//______________________________________


technique ParticleInstancing
{
	pass
	{
		VertexShader = compile VS_SHADERMODEL
			VertexShader01();
		PixelShader = compile PS_SHADERMODEL
			PixelShader01();
        //AlphaBlendEnable = TRUE;
        //DestBlend = INVSRCALPHA;
        //SrcBlend = SRCALPHA;
    }
};

// in this version the alpha will increase the size of the particle.
technique ParticleInstancing02
{
    pass
    {
        VertexShader = compile VS_SHADERMODEL
			VertexShader02();
        PixelShader = compile PS_SHADERMODEL
			PixelShader01();
    }
};


// These will be the new additions to the shader from the last example.


struct VSInstanceInputTimed02
{
    float3 InstancePosition : POSITION1; // ahh wait waat .... like i must have accounted for this at some point and didn't change the cs file as well ... omg there is a lesson here.
    float InstanceTimeOrId : BLENDWEIGHT0;
    float4 InstanceColor : COLOR1;
};

struct VSVertexInputTimed02
{
    float4 Position : POSITION0; //SV_POSITION;
    float2 TexCoord : TEXCOORD0;
    //uint InstanceId : SV_InstanceId;
};

struct VSOutputTimed02
{
    float4 Position : SV_POSITION;
    float2 TexCoord : TEXCOORD0;
    float4 Color : COLOR0;
};


VSOutputTimed02 MainVSTimed02(in VSVertexInputTimed02 vertexInput, VSInstanceInputTimed02 instanceInput)
{
    VSOutputTimed02 output;
    output.TexCoord = vertexInput.TexCoord;
    float3 InstancePosition = instanceInput.InstancePosition;
    float InstanceTimeOrId = instanceInput.InstanceTimeOrId;
    float movingTime = InstanceTimeOrId * TotalTime + TotalTime;
    float4x4 vp = mul(View, Projection);
    float4x4 wvp = mul(World, vp);
    float4 posVert = mul(vertexInput.Position, wvp);
    float4 posInst = mul(instanceInput.InstancePosition.xyz, wvp);
    float4 pos = (posVert + posInst);
    output.Position = pos;
    // uncomment the below line for super trippy mode lol
    output.Position = pos * sin(movingTime * PI2);
    output.Position.x = pos.x * cos(movingTime * PI2) - pos.y * sin(movingTime * PI2);
    output.Position.y = pos.x * sin(movingTime * PI2) + pos.y * cos(movingTime * PI2);
    // change color
    output.Color = instanceInput.InstanceColor;
    return output;
}

float4 MainPSTimed02(VSOutputTimed02 input) : COLOR0
{
    float4 col = input.Color * tex2D(TexSampler, input.TexCoord);
    //clip(col.a - .05f); // straight clip alpha draws
    return col;
}



technique ParticleDrawingTimed02
{
    pass
    {
        VertexShader = compile VS_SHADERMODEL
        MainVSTimed02();
        PixelShader = compile PS_SHADERMODEL
        MainPSTimed02();
    }
};

The texture i used for the example right click on it and save image.

smokeSmall02b

1 Like