How can I combine (merge) two Normal output (not Normal Map, and not with LERP)? Is it possible? If possible, I want learn with its mathematical base.

# How Combine (Merge) Two Normal Output (Not Normal Map)?

What do you mean by merge?

Normals are just vectors so look into vector math.

Daniel Shiffmanâ€™s Nature of Code is good introduction to math as it applies to creating images.

If you want the average of the vectors, lerping is fine, just normalize afterwards if you want a normal vector. The vector c that bisects two vectors a and b is = (a+b)/2, the half vector of a and b.

Adding two vectors is just adding the components and can be done with a vector math/add node. Multiplying or dividing a vector to scale it, like in the half vector above, is just multiplying or dividing all components (can be done with a MixRGB node, but for some reason thereâ€™s no vector scale in vector math.)

Iâ€™ve had a lot of fun playing with a custom rotateAxisAngle node that I made to rotate vectors around arbitrary axes; that might be something you want instead. I used https://en.wikipedia.org/wiki/Rodriguesâ€™_rotation_formula to build it. You have to make your own cross product node out of basic math though, because Blenderâ€™s cross product isnâ€™t really the cross product, itâ€™s the normalized cross product, which you donâ€™t want.

Thanks. But no, not with LERP or Add. I want combine perfectly, not want average of vectors.

And thanks, I know rotate a vector.

Average of vectors *is* the vector that *perfectly* bisects two vectors. For the case of unit length vectors.

No, this give me mixed result and this is invalid, I want layered result. Second normal must transform to First normal.

No. This is Merge Normal Maps. I want merge Normal vectors.

Itâ€™s the same math (a simplified quartenion multiplication)! the only thing it needs is to remove the scalings from [-1,1] to [0,1] and vice versa.

How? Can you tell me more clearly?

Show me what youâ€™re doing. Nodes and inputs and meshes. The language here is unclear: â€śmergeâ€ť, â€ścombineâ€ť are not specific terms.

Then think about what youâ€™re doing. You want to start with two vectors that represent a rotation off a normal to start with? (Rotation off unmodified normal, possibly true normal.) And then you want to add those two rotations? You can do that. The axis of your rotation for each vector is the cross product of the original normal and the new normal. The magnitude of that rotation is the arccos of the dot product of those two vectors. You can start with your original normal, rotate it to the position of the first modified normal, then rotate it again according to the transformation represented by the second modified normal.

The very first thing done in that link, line 1 (and 2) of the code, is to convert normal map lookups into normal vectors. â€śtex2D(texBase, uv).xyz*2-1â€ť is lookup up the color, multiplying it by 2, and subtracting 1 to convert the lookup into a tangent space vector. If youâ€™re talking about starting with normals instead of normal map lookups, all you have to do is skip that transformation, as you already have normalized vectors in the -1,1 range.

Thanks. I saw HLSL code now. I will investigate this code and your tells.

hereâ€™s an old nodegroup for rotating vectors with quaternion multiplicationsâ€¦

quaternion_rotation.blend (613.7 KB)

with it you can rotate a vector around an axis (another vector), by some angle.

I have another (simplified version) that just rotates the normal vector around some tangent vectorâ€¦ itâ€™s pretty straigthforward: [cross(N, Tg) * sin(angle)] + [N * cos(angle)]

Thanks. But quaternion rotation node is too cost.

This method is not work for Blender, because Blenderâ€™s normal type is different. This code works with normal maps but not work with normal values (I removed color to normal conversion).

float3 n1a = texture2D(base_map, uv).xyz;

float3 n2a = texture2D(detail_map, uv).xyz;

float3 n1 = float3(n1a.z, n1a.x, n1a.y); // Convert from Blender normal type

float3 n2 = float3(n2a.z, n2a.x, n2a.y); // Convert from Blender normal type

// We have to 180 degree rotate on the Z axis for convert from Blender normal type.

float3 n = n1*dot(n1, n2)/n1.z - n2;

But not work properly. Result is â€śBlender Object Space Normal Mapâ€ť, not Normal and not properly. And if I need to add new operations, then this will be too cost, especially for Eevee.

I took another look at the code-- sorry, it does need to happen in tangent space, because there are some things specific to the normal.

But I went ahead and recreated it (the â€śpartial derivative blendingâ€ť version.) Looks all right to me, especially considering the sources I used donâ€™t look too hot. Scaled the normal map strength to eye.

As always with tangent normal maps, you need to pay attention to your tangents. This plane was built world Z-up, with +U pointing in world +X-- ie, the orientation where tangent space = object space.

If your goal is not to actually combine two normal maps in some way, but to instead combine two normals, Iâ€™m afraid that doesnâ€™t make much sense to me, and I would need a lot more explanation about the end-goal. These combinations depend not just on two normals, but additionally on a normal and a tangent. Because what weâ€™re actually doing is combining the difference between normal1/normal2 and normal1/normal3-- your mesh normal plays a role. (And a tangent is involved in the process, because weâ€™re evaluating in tangent space so that we can know that blue/z means the in the direction of normal1.)

Also: donâ€™t rotate world space normals 180 degrees to convert. The most common thing youâ€™d need to do to convert is to invert the green channel, while itâ€™s still a color and not a vector. But there are a lot of things in your node group that donâ€™t make a lot of sense to me, and it doesnâ€™t seem to represent any of the code that I can see (none of which involves a dot product.)

Thanks, but this is â€śMerge Normal Mapâ€ť, but I need â€śCombine Normalsâ€ť, so I need combine â€śNormalâ€ť outputs (Purple sockets). I only show an example with Normal Maps, bu not needs use Normal Map, it have to works with all â€śNormalâ€ť outputs.

â€śInvert Greenâ€ť not works with â€śNormalsâ€ť, only works with â€śTangent Space Normal Mapsâ€ť.

I donâ€™t know this is possible, but I research this thing.

What that does is merge two normal maps with one normal vector (your mesh normals).

Thatâ€™s part of why Iâ€™m confused by you talking about merging two normals.

If you had two maps of *world space* normals, you could combine them with each other and with the mesh normal, although itâ€™s complex and slow. It is possible to make a world space to tangent space node, which would let you plug world space vectors into the above node group. Again, complex and slow, and youâ€™ve already indicated youâ€™re not interested in anything with those qualities.

If your goal does not involve normal maps, can you show me what your goal is? Where are your two normals coming from? What are they, how are they generated? Are you actually wanting to combine them with a third normal, like a mesh normal?

Thanks. Yes, I know this method but this is very cost. I want direct combine.