# GLSL lookAtMatrix stability

I’m calculating a “look at matrix” inside a vertex shader. It pretty much works, but in certain moments there’s a drastic rotation that I want to avoid. In the attached image, you can see a sphere at the top. The sphere is the lookAt target. The sphere moves only a little between the two renders, but the rotation around the lookAt axis is nearly 180 degrees. Am I supposed to add a non-zero and dynamically calculated roll value to calcLookAtMatrix to avoid this big rotation? I can add a constant roll value, but then the problem just shows up in a different situation.

[code]mat3 calcLookAtMatrix(vec3 origin, vec3 target, float roll) {
vec3 rr = vec3(sin(roll), cos(roll), 0.0);
vec3 ww = normalize(target - origin);
vec3 uu = normalize(cross(ww, rr));
vec3 vv = normalize(cross(uu, ww));

``````return mat3(uu, vv, ww);
``````

}[/code]
lookAtMatrix_glsl_question.1.toe (15.5 KB)

This is happening when the vector ‘rr’ is colinear with ww. This is a common problem with look-ats, as you need to define your ‘up’ vector to be somethig other than ‘up’, when you want to look ‘up’

Thanks now you’ve got me thinking about the cross product of up and the lookat. If I do the classic right-handed rule where my index is the up vector and my middle is the lookAt, my thumb points towards me. If I uncross my fingers by moving the lookAt just a little, my thumb points away from me. That’s the rotation that I want to avoid. In the case that lookAt and up are nearly colinear, the cross product is nearly on the XZ plane. I’m thinking about taking the atan of this 2D XZ vector and doing some other modulus operation to calculate a roll. Does that sound familiar or is it a dead end?

Sounds plausible. Anything that generates a stable up vector in the colinear case (you gotta decide where you want it go be, toward +Z or +Z, or something else) should work

I sort of gave up and concluded that there isn’t a time-independent way to get a stable up vector. The up vector at the current frame needs to refer to previous information such as the previous up vector and right vector…

I looked at this as code reference
[url]https://github.com/keijiro/Swarm/blob/master/Assets/Swarm/Shader/SwirlingSwarm.compute[/url] and was able to get a stable up vector in my tube renderer.