I’m writing my own billboards, and i want them to use normal maps for lighting. I’m having hard time figuring out how to calculate tangent and binormal vectors.

I assumed, I can take direction towards the camera as normal, and then calculate right and up vectors as tangent and binormal. All in world space.

I’ve got pretty close to wanted result with this GLSL code:

VS:

```
vec3 camUp = vec3(cCameraRot[0][1],cCameraRot[1][1],cCameraRot[2][1]);
vec3 Dir = normalize(cCameraPos-worldPos);
vec3 Right = normalize( cross( Dir , camUp));
vec3 Up = normalize( cross( Right, Dir ) );
vNormal = Dir;
vBinormal = Up * -1;
vTangent = Right;
```

PS:

```
vec4 nmMap = texture2D(sDiffMap, vTexCoord.xy);
if (nmMap.a < 0.5)
discard;
mat3 tbn = mat3(vTangent, vBinormal, vNormal);
vec3 normal = DecodeNormal(nmMap) * tbn;
```

It looks alright, from all directions, but only as long as camera stays in parallel with horison. Looking top-down or changing camera rool will break proper orientation.

I’ve tried many other things, my brain is boiling up from all this vectors and matrices, and result is always crooked.

So, what am I missing here? What else can I try?