How to transform normal from tangent space to world space?

Background:
I am working on shader for landscape with virtual heightfield mesh (VHM). It consists of two parts: static (RVT cache) and dynamic (weather). For the second part I need to blend snow with RVT cache based on collection parameter. I create snow material, it has normals in tangent space so I convert it into world space with help of “TransformVector” node. It works with landscape but does not work with VHM. My guess VHM is just plane and does not have same information about normals and tangents.
So I came up with idea to pipe normals and tangets with help of another RVT.

Question:
How to transform normal from tangent space to world space by using vertex normals and vertex tangents?
I found this formula:
float3 ws_normal = tangent * ts_normal.x + binormal * ts_normal.y + normal * ts_normal.z;
and implemented function:


This is my test setup:

But it does not work same as “TransformVector” node. What am I missing?

Well, you get binormal in a wrong way.
To get the right binormal, a particular “sign” for binormal is required.
Like this:

// vNt is the tangent space normal
vB = sign * cross(vN, vT);
vNout = normalize( vNt.x * vT + vNt.y * vB + vNt.z * vN );

Hello, I’m a little late to the party. @papahuhu is right here, binormals are wrong. You need to flip inputs in cross and this should be good to go.
There is small issue with solution from 모야봉. When you compare TransformVector (Tangent Space to World Space) with this solution you have issues with blue channel from normal map. You simply need to also multiply and add blue channel to equation. There is also a simple way to calculate this using Transform3x3Matrix function.

Additionally if you want to convert World Space to Tangent Space you can use InverseTransformMatrix.
Big kudos to @Adder1812 for helping me understand the topic

2 Likes

:heart: np :)) (why the F. FIX142 link to me leads to 404 :smiley: )

1 Like

Same her thanks so much your a life saver