thx

nice indeed, thanks

btw, how come the tbnMat is calculated this way ? (with a multiplication of the binormal)

`mat3 tbnMat = mat3(wvTangent, wvBinormal * inTangent.w,wvNormal);`

in the literature, the matrix multiplication is matrix first, in lighting.vert, it is the other way aroundā¦ is it becos of JME is righthanded instead of lefthanded ?

`vPosition = wvPosition * tbnMat; `

here in OpenGL 4 Shading language cookbook

```
mat3 toObjectLocal = mat3(
tang.x, binormal.x, norm.x,
tang.y, binormal.y, norm.y,
tang.z, binormal.z, norm.z ) ;
...
LightDir = normalize( toObjectLocal * (Light.Position.xyz - pos) );
```

The multiplication of the binormal is because some binormals need to be inverted depending on the triangle.

The inversion of the matrix multiplication is also a math trick.

The tbnMat transforms view space to tangent space, but we actually need it the other way around. so weād need to actually invert the matrix. Inversion is an expensive process, and the glsl āinvertā function need glsl 1.3 as far as I remember.

Iām not good at math, so I could be wrong in the explanations, but thatās something along those lines :

So the trick is that when you have a normalized rotation matrix (like the tbn mat) you can actually just transpose it instead of inverting it. And since mat * vec = vec * transpose(mat), we just have to invert the direction of the multiplication to have the result we want.

That trick saves a lot of operations in the frag shader. And as the nice side effect of working

nice indeed