Sign in to follow this  
fire67

How to blend World Space Normals

Recommended Posts

Hey everyone,
 
I am trying to blend two world space normals inside a shader. One comes from a tangent space normal map converted into world space using a classic TBN matrix and the other one is a mesh normal map in world space.
 
I found some interesting resources here :
But those blending technics seem to be only available for tangent space normals, especially the Reoriented Normal Mapping (RNM).
I tried to apply the RNM technic with unpack already done.
n1 += vec3(0, 0, 1);
n2 *= vec3(-1, -1, 1);

return n1*dot(n1, n2)/n1.z - n2;

But this doesn't give expected results and I don't get why. Is there a way to apply the RNM blending on world space normals ?

 
Thanks a lot !
Edited by fire67

Share this post


Link to post
Share on other sites

Here are the outputs which are obtain using this, expect when outputing only the normals.

float3 nv = dot(normal, viewDir);
color.rgb = nv;

[attachment=31554:total.jpg]

 

Here is the RNM function I am using :

n1 += float3(0.0, 0.0, 1.0);
n2 *= float3(-1.0, -1.0, 1.0);

return n1 * dot(n1, n2) / n1.z - n2;

As you can see in the bottom screenshot, I would like like some kind of blending between both normal map and I don't really know what's happing but the A normals should be disturbed by the B normals or it seems to give another result.

Edited by fire67

Share this post


Link to post
Share on other sites

From what i remember at least some of those blending functions assume Z to point upwards, means they work in tangentspace. So they blend normalmaps, not normals.

Also i don't get why you want to blend the mesh normal with a normalmap converted to worldspace via TBN since the TBN orients tangentspace-normalmaps to your mesh.
To me it looks like you get kind of double oriented normals.

 

I used the partial derivate function to add some additional detail, but i blended it in tangentspace and then converted the resulting normal to worldspace via TBN.

Share this post


Link to post
Share on other sites

The sample implementation of RNM on that blog post assumes that the "s" vector is a unit z vector, which is the case for tangent-space normal maps. This is represented in equations 5/6/7. If you want to work in world-space, then you need to implement equation 4 as a function that takes s as an additional parameter:

 

float3 ReorientNormal(in float3 u, in float3 t, in float3 s)
{
    // Build the shortest-arc quaternion
    float4 q = float4(cross(s, t), dot(s, t) + 1) / sqrt(2 * (dot(s, t) + 1));
 
    // Rotate the normal
    return u * (q.w * q.w - dot(q.xyz, q.xyz)) + 2 * q.xyz * dot(q.xyz, u) + 2 * q.w * cross(q.xyz, u);
}

 

If you pass float3(0, 0, 1) as the "s" parameter, then you will get the same result as the pre-optimized version. However the compiler may not be able to optimize it as well as the hand-optimized code provided in the blog.

Share this post


Link to post
Share on other sites

From what i remember at least some of those blending functions assume Z to point upwards, means they work in tangentspace. So they blend normalmaps, not normals.

Also i don't get why you want to blend the mesh normal with a normalmap converted to worldspace via TBN since the TBN orients tangentspace-normalmaps to your mesh.
To me it looks like you get kind of double oriented normals.

 

I used the partial derivate function to add some additional detail, but i blended it in tangentspace and then converted the resulting normal to worldspace via TBN.

 

Thanks for your answer @Ryokeen. In the original paper, they are baking the bent world normal into the vertex color.

Then they are using those bent vertex normals to calculate the TBN and calculate a bent version of the world normals using the normal map. Unfortunately, I am not able to use the vertex color that's why I am using a bent world normal texture to re-orientate the normals. :(

 

Thank you for the code @MJP !

I Understand what you mean concerning the z vector unit. But I think that I am missing something because I don't know which other vector should I use for this unit vector.

 

Another thing that I don't get is why (especially visible on the cheek) the normals are so much perturbed.

When outputting only world normals A and B (see previous screenshots) the value seems to be close to (x, y, 1) and when blending, no matter the classic RNM technic or yours (see screenshot below) the combined normals become black and closer to (0, 0, 0).

 

Why the values are changing so much ?

 

[attachment=31563:normal.jpg]

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this