Gpu particles: how to color particles individualy in pixelshader?

as the topic says i try to find a pixelshader function which let me control particle color individualy.
i have a texture with rgba color values and texturecoordinates for the single particles, like in dottores lib.

when i use the tex2Dlod function in the pixelshader, the first pixels rgba value of the texture gets assigned to all particles. this is not what i expected.

float4 col = tex2Dlod(SampData3, In.TexCd2);

whats the problem here?

+1… no text …

ah io. try this shader. it uses 3 data textures. first for position and size. second for yaw pitch roll and third for rgba.

you migth change the texturecoordinates according to your mesh. i used texcoord3 for the particles.

SimpleParticles3DataTextures.fx (4.6 kB)

Just make sure you are referencing the same texture coordinates, and have the same size texture as your positions and you should be good.

I still don’t get how you generate the initial textures (to control position/size/colour etc) with any precision, without using a heavy cpu process like a massively spreaded dynamic texture…

the only way to avoid dynamic textures for the initial buffers right now would be prerendered textures…

brings me to the thougth of reading out a prerendered movie file as texture input for a particle system. at the first climpse opposing when thinking in terms of real time rendering. but could be a technique for visualizing large datasets with change over time. like when working with global climate data…

another thougth is one could build some kind of particle depth map for video input by simply spanning a particle plane on x,y with the resolution of the videotexture and assigning the pixel values to the z axis…
but im sure one of you did it allready :)

could help me to understnad where and how to use this fx, like in which GPU partcles context?

You can also use the colour input in the vertex buffer join node to colour individual particles, but its not very intuitive…

the fx i posted is basically the same as the one from ParticlesGPU_3d_Static Allocator in the lib, just with messy code :)

//vari::udo 12.12.2014
//@author: vvvv group
//@help: basic pixel based lightning with directional light
//@tags: shading, blinn

// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------

float4x4 tW: WORLD; //the models world matrix
float4x4 tV: VIEW; //view matrix as set via Renderer (EX9)
float4x4 tWV: WORLDVIEW;
float4x4 tP: PROJECTION; //projection matrix as set via Renderer (EX9)

  • include <effects\PhongDirectional.fxh>

//position texture
texture TexData <string uiname=“Data Texture”;>;
sampler SampData = sampler_state //sampler for doing the texture-lookup
Texture = (TexData); //apply a texture to the sampler
MipFilter = none; //sampler states
MinFilter = none;
MagFilter = none;


texture ColorTex <string uiname=“Color”;>;
sampler SampColor = sampler_state
Texture =(ColorTex);
MipFilter = none;
MinFilter = none;
MagFilter = none;


texture Tex <string uiname=“Texture”;>;
sampler Samp = sampler_state //sampler for doing the texture-lookup
Texture = (Tex); //apply a texture to the sampler
MipFilter = LINEAR; //sampler states
MinFilter = LINEAR;
MagFilter = LINEAR;

float4x4 tTex: TEXTUREMATRIX <string uiname=“Texture Transform”;>;
float4x4 tColor <string uiname=“Color Transform”;>;

struct vs2ps
float4 Vcol : COLOR ;
float4 PosWVP: POSITION;
float4 TexCd : TEXCOORD0;
float3 LightDirV: TEXCOORD1;
float3 NormV: TEXCOORD2;
float3 ViewDirV: TEXCOORD3;


// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------

vs2ps VS(
float4 Vcol : COLOR ,
float4 PosO: POSITION,
float3 NormO: NORMAL,
float4 TexCd : TEXCOORD0)
//inititalize all fields of output struct with 0
vs2ps Out = (vs2ps)0;

//get the position info from the Position-velocity texture:
float3 particlePosition = tex2Dlod(SampData, TexCd).rgb;

//apply the tW (points at the mesh position)
PosO = mul(PosO, tW);

//now apply the position taken from the texture += particlePosition; = tex2Dlod(SampColor, TexCd);

//then apply the tVP += mul(, tP);

//inverse light direction in view space
Out.LightDirV = normalize(-mul(lDir, tV));

//normal in view space
Out.NormV = normalize(mul(NormO, tWV));

//position (projected)
Out.PosWVP  = mul(PosO, tWVP);
Out.TexCd = mul(TexCd, tTex);
Out.ViewDirV = -normalize(mul(PosO, tWV));
return Out;


// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------

float Alpha = 1;

float4 PS(vs2ps In): COLOR
//In.TexCd = In.TexCd / In.TexCd.w; // for perpective texture projections (e.g. shadow maps) ps_2_0

float4 col = tex2D(Samp, In.TexCd);

col.rgb *= PhongDirectional(In.NormV, In.ViewDirV, In.LightDirV);
col.a *= Alpha;

return mul(col, tColor);


// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------

technique TPhongDirectional
pass P0
//Wrap0 = U; // useful when mesh is round like a sphere
VertexShader = compile vs_3_0 VS();
PixelShader = compile ps_3_0 PS();

technique TFallbackGouraudDirectionalFF
pass P0
NormalizeNormals = true;
WorldTransform0 = (tW);
ViewTransform = (tV);
ProjectionTransform = (tP);

    MaterialAmbient  = {1, 1, 1, 1};
    MaterialDiffuse  = {1, 1, 1, 1};
    MaterialSpecular = {1, 1, 1, 1};
    MaterialPower    = (lPower);

    Sampler[0](0) = (Samp);
    TextureTransform[0](0) = (tTex);
    TexCoordIndex[0](0) = 0;
    TextureTransformFlags[0](0) = COUNT2;
    //Wrap0 = U;  // useful when mesh is round like a sphere

    LightEnable[0](0) = TRUE;
    Lighting       = TRUE;
    SpecularEnable = TRUE;

    LightType[0](0)     = DIRECTIONAL;
    LightAmbient[0](0)  = (lAmb);
    LightDiffuse[0](0)  = (lDiff);
    LightSpecular[0](0) = (lSpec);
    LightDirection[0](0) = (lDir);

    ShadeMode = GOURAUD;
    VertexShader = NULL;
    PixelShader  = NULL;


above: PhongDirectional variation, accepting particles input_mesh with an additional data_texture input