Total: 3 + 4 + 3 = 10 floats = 40 bytes per particle (vec3, vec4, vec3)
I
vec3 = unpacked positional information
II
vec4 = packed source and destination colors: float0 = src color, float1 = src alpha, float2 = dst color, float3 = dst alpha
III
data packing is done as:
//particle data packing into vec4
//float0
// bits function
// 0 - 4 texture index in the atlas (0-15)
// 4 - 8 stage
// 8 - 16 persistence (0-255) (essentially decay rate)
// 16 - 20 target scale (0-15)
// 20 - 24 current scale (0-15)
// 24 - 32 rotation (0-255)
//float1
// stage age not packed
//float2
// velocity not packed
//float3
// packed direction vec3 packed into a float
//Rotation speed is deduced from particle stage and persistence.
The vec3->float->vec3 packing functions are:
vec3 Float2Vec3(in float f)
{
vec3 color;
f *= 256.0;
color.x = floor(f);
f -= color.x;
f *= 256.0;
color.y=floor(f);
f -= color.y;
color.z = floor(f*256.0);
return color*0.00390625; // color/256
}
float Vec32Float(vec3 color)
{
const vec3 byte_to_float = vec3(1.0, 1.0 / 256.0, 1.0 / (256.0 * 256.0));
return dot(color, byte_to_float);
}
If anyone has any suggestions on how to do this even better or how to increase precision, by all means please post some feedback!