hi, guys,

I want to know why we can use the **v.tangent.w** as multiplier to control the direction of Binormal:

For tangent space normals the binormal is always perpendicular the normal and the tangent. The orientation of a cross product in relation to the other two vectors is consistent, so all you need to know is if the actual binormal is in the direction of the cross product or not.

What I find that helps me (I’m not sure if this is what you mean) but with cross products, it can get tricky if you’re switching between right handed coordinate systems (like mathematics, Maya/Blender/modeling software uses) and left handed coordinate systems (like video games/Unity). This is how I remember it in my head:

Think of the standard basis vectors. It sounds scary but it’s the vectors i = (1, 0, 0), j = (0, 1, 0), and k = (0, 0, 1) that align with the x, y, and z axes (in that order), each one unit in length to make the math easier. No matter what coordinate system you’re using, left or right handed, if you’re in 3D, i always points in the positive x axis, j always points in the position y, and k always the positive z.

With that in mind, i crossed with j is defined to equal k (i x j = k) no matter what. This is nice for me to see in my head cause they align exactly with the xyz axes! So whenever you’re dealing with a cross product, say you need to cross a normal vector and a tangent vector (in that order) to get a binormal vector, you can just visualize the normal as aligned with the x axis in your head, and the tangent aligned with the y axis. Then the binormal will be aligned with the z axis. If you instead cross the tangent vector with the normal vector (same two vectors, but reversed order from before), then align the tangent with the x-axis instead, and the normal with the y-axis.

[EDIT] - Oh and as to why they multiply v.tangent.w? I’m wondering the same thing now haha, I usually just cross the normal and tangent, no need for a multiplier. Regardless though, that would only change the length of the binormal, its direction would not be changed by scaling it bigger/smaller.

Because the binormal direction is defined by the orientation of the UVs. For a mirrored or unmirrored UV the binormal will either match the cross product or be the inverse. The tangent.w component is this always 1 or -1 to handle that.

Hmm I’m not sure I fully understand. The tangent is usually aligned in the positive U direction, right? The normal will always be perpendicular, and the binormal will be aligned in the positive v direction then? And the 1 or -1 thing is based on if the platform has UV spaced vertically flipped or not then, right? (Cause certain platforms have v = 0 at the top, increasing to v = 1 at the bottom)

The tangent is always aligned to the positive U direction, yes. But the bitangent (aka binormal) is also aligned (roughly) to the positive V direction. As you stated, cross(normal, tangent) results in a vector that is in a particular “handedness”, and by default for Unity that is inverted from the intended bitangent direction. So the default value for v.tangent.w is -1.0.

However, if the UVs are mirrored, not because of the platform*, but because the content is authored as such, the binormal will now be in line with the cross product and v.tangent.w is set to +1.0. Think of a character’s face where the texture only contains half of the face in it and the other side is just mirrored across, this would mean the w component would need to be +1 on one side and -1 on the other.

- Unity’s mesh UVs, bitangent orientation (v.tangent.w), and normal maps are all using OpenGL’s UV coordinate system, i.e.: UV 0,0 is at the bottom left of the texture. For supporting different platforms where the V direction is flipped, like DirectX, Unity simply uploads the textures to the GPU upside-down so no changes to the mesh vertex data is needed.

Ohh I see, wow thanks for explaining all of that that makes a lot more sense now.

thank you for clear explanations