With the help of Arne Reiners, I implemented a particle system that rotates the particles according the camera rotation; this is a cheap and fast way to handle it.
However, I am finding that for lighting I need more accurate orientations. It is easy for me to find the vector between the camera position and particle center. How can I use that information to set the particle vertices so they only depend on camera position and not rotation?
Here is my current particle vertex shader:
uniform float AppTime;
uniform vec2 ParticleOffset[4];
uniform float RotationSpeed;
uniform float ParticleCount;
uniform float ParticleCycle;
uniform float ParticleTick;
varying vec3 VertexPosition;
varying vec2 texcoord0;
varying vec2 texcoord1;
uniform mat4 CameraMatrix;
varying vec3 ParticlePosition;
varying vec3 N;
void main(void) {
float cycle;
float index;
if (gl_Vertex.w==-1.0) {;
// Particle is hidden
gl_Position = vec4(0.0,0.0,0.0,0.0);
gl_FrontColor=vec4(1.0,1.0,1.0,0.0);
}
else
{
gl_FrontColor=gl_Color;
index = floor( gl_Vertex.w / 4.0 );
cycle = mod(ParticleCycle + (index * ParticleTick)/(ParticleTick * (ParticleCount-1)),1.0);
// Scale
float radius = cycle * 0.05 * 100.0;
// Fade in
if (cycle<0.1) {
gl_FrontColor.a*=cycle/0.25;
}
// Fade out
if (cycle>0.75) {
gl_FrontColor.a*=(1.0-cycle)/0.25;
}
vec4 v = gl_ModelViewMatrix * vec4( gl_Vertex.xyz, 1.0 );
vec3 ov = ( CameraMatrix * v ).xyz;
ParticlePosition = (gl_ProjectionMatrix * v).xyz;
vec2 offset = ParticleOffset[ int(mod( gl_Vertex.w, 4.0 )) ];// * radius;
// Rotation
float seed = ( ( index * 169.0 + AppTime ) / 1000.0 ) * 3.14159265 * 2.0 * RotationSpeed;
if ( (floor( index/2.0 ) * 2.0) == index ) {
seed *= -1.0;
}
float sa = sin( seed );
float ca = cos( seed );
v.x += sa * offset.y * radius - ca * offset.x * radius;
v.y += -ca * offset.y * radius - sa * offset.x * radius;
texcoord0 = offset * 0.5 + 0.5;
texcoord1.x = sa * offset.y - ca * offset.x;
texcoord1.y = -ca * offset.y - sa * offset.x;
texcoord1 = texcoord1 * 0.5 + 0.5;
VertexPosition = ( CameraMatrix * v ).xyz;
N = normalize(VertexPosition - ov);
N = normalize(gl_NormalMatrix * N);
gl_Position = gl_ProjectionMatrix * v;
}
}