*Bounty: 100*

*Bounty: 100*

**Behavior:**

With the following texture

I get a weird behavior when I try to rotate my particles in the direction they are moving. Essentially, the quad seems to rotate, but just barely so that when they bounce on the ground or when they spawn we can clearly see that they are not aligned upward when the particle is going upward.

**Shader code and process explanation:**

**particle_billboard.geom:**

```
//This geometry shader takes points as a
//primitive input and return quads built with
//triangle strips
#version 430
layout (points) in;
layout (triangle_strip, max_vertices = 4) out;
layout (std140, binding = 0) uniform CameraInfo {
mat4 ProjectionView; // Projection * View
vec3 eye; // camera position
};
uniform float particle_size;
in vec4 ex_Color[];
in vec3 ex_Direction[]; // Only one direction per particle so index is always direction[0]
out vec2 TexCoord;
out vec4 FragColor;
float angle_between_vector(vec3 v1, vec3 v2)
{
return acos(
dot(v1, v2)/ length(v1)*length(v2)
);
}
vec3 project_vector_on_plane(vec3 v, vec3 normalized_plane_normal)
{
return v - dot(v, normalized_plane_normal) * normalized_plane_normal;
}
vec4 quat_from_axis_angle(vec3 axis, float rad_angle)
{
vec4 qr;
float half_angle = 0.5*rad_angle;
qr.x = axis.x * sin(half_angle);
qr.y = axis.y * sin(half_angle);
qr.z = axis.z * sin(half_angle);
qr.w = cos(half_angle);
return qr;
}
vec3 rotate_vertex_position(vec3 position, vec3 axis, float rad_angle)
{
vec4 q = quat_from_axis_angle(axis, rad_angle);
vec3 v = position.xyz;
return v + 2.0 * cross(q.xyz, cross(q.xyz, v) + q.w * v);
}
void main(void) {
// Built-in variable "gl_in" of the geometry shader
// gives us the index in the primitive. Points only
// have one index, so gl_in[0] it is.
vec3 wPos = gl_in[0].gl_Position.xyz;
vec3 wRotatedPos = wPos;
vec3 originalPos = wPos;
vec3 wPosToCamera = normalize(eye - wPos);
vec3 wUp = vec3(0.0, 1.0, 0.0);
vec3 wRight = cross(wPosToCamera, wUp);
FragColor = ex_Color[0]; // Points only have one vertex
// 0.1 - Project ex_Direction on
// 1- Compute angle between right and direction
float wDirectionAngle = angle_between_vector(project_vector_on_plane(ex_Direction[0], wPosToCamera), wRight);
// Lower left corner
wPos -= (wRight * particle_size/2);
wPos.y -= particle_size/2;
wRotatedPos = rotate_vertex_position(wPos - originalPos, wPosToCamera, wDirectionAngle) + originalPos;
gl_Position = ProjectionView * vec4(wRotatedPos, 1.0);
TexCoord = vec2(0.0, 0.0);
EmitVertex();
// Upper left corner
wPos.y += particle_size;
wRotatedPos = rotate_vertex_position(wPos - originalPos, wPosToCamera, wDirectionAngle) + originalPos;
gl_Position = ProjectionView * vec4(wRotatedPos, 1.0);
TexCoord = vec2(0.0, 1.0);
EmitVertex();
// lower right corner
wPos.y -= particle_size;
wPos += wRight * particle_size;
wRotatedPos = rotate_vertex_position(wPos - originalPos, wPosToCamera, wDirectionAngle) + originalPos;
gl_Position = ProjectionView * vec4(wRotatedPos, 1.0);
TexCoord = vec2(1.0, 0.0);
EmitVertex();
// Upper right corner
wPos.y += particle_size;
wRotatedPos = rotate_vertex_position(wPos - originalPos, wPosToCamera, wDirectionAngle) + originalPos;
gl_Position = ProjectionView * vec4(wRotatedPos, 1.0);
TexCoord = vec2(1.0, 1.0);
EmitVertex();
EndPrimitive();
}
```

That is pretty much it for the code, I don’t really do much else in the vertex and frag shaders… But I can provide them if necessary.

First of all, I draw the particles with quads that I build in the geometry shader from a single point. The quads are built with a `right`

and `up`

vector a little bit like this tutorial does, mainly for making the quads always face the camera.

Now, I visualize the texture as being aligned with the `right`

vector, so I try to compute the angle (`wDirectionAngle`

) between this vector and the direction vector of the particle projected on the camera plane. The camera plane being the plane with the normal in the same direction as the *particle_position-to-camera-vector* “`wPosToCamera`

“. Finally, I use the `wPosToCamera`

as a quaternion vector to rotate my generated quads coordinate around the center of the quad. The rotation around the quaternion and the parameters I use are also heavily inspired on this tutorial.

I’ve debugged the direction angle and it appears to be correct, although I’m not 100% sure. What could possibly cause this to happen, is there a flaw in the logical process? I couldn’t really get any inspiration of similar posts, since they are all about 2D.