Recompute tangents and normal maps, I have found a solution

No clue how often I have landed on this answerhub page: I have posted the same solution there.

In your material turn off “Tangent space normal”, then use the “Derive Tangent Basis” function with your normal map and plug the “World Space Normal” output into your materials “Normal” input.


Now, the question is why do I have to do this? From my comparison screenshot, it’s clear that it isn’t a problem related to the seams of the mesh because the tangent base seems to be wrong pretty much everywhere (at the seams it just becomes extra apparent because of the visible line there). Usually, the behavior is that the engine provides you with a correct tangent space for your TexCoord 0 (This is what happens for static meshes and when recompute tangents is turned off). Is there a good reason for this or is this just a bug and ticking tangent space normal should give correct results?

1 Like

Just bumping this thread up, I have heard back from epic after sending in a bug report and providing a sample project a few days ago. The bug was fixed internally and is coming in a future version. So this workaround hopefully won’t be needed for much longer.

As of 4.25.0 there is still seams when using compute skincache. I wonder if anyone has ever used that feature so far as its pretty pointless as it is right now (disregarding any workarounds).

In 4.25 the seams are back and the workaround doesn’t do anything anymore. Is Epic ever going to do something about this? It’s been 3 years since it was reported.

In 4.25.1 it looks much worse than ever before, even without any normal map there are extremely visible seams (this time even on the diffuse texture material, which are visible in Lit Mode, but not in Unlit Mode, so it is no problem with the uv layout, but with the skincache), with “support compute skincache” checked.

Support compute skincache is important for using Dual Quaternion Skinning Mode, because without it there are ugly shadows at spots like armpits, where JCMs/Morph Targets are being used (for bulge reduction), esp. with poses like arms up etc. Most people won’t even notice this as they only use some standing/idle or walk anims, but my project heavily depends on regularly using animations like gym exercises, fighting, dancing, stretching, where this glitch is very visible and thus annoying etc.

Even in 4.24 the workout from above didn’t really help and I was never able to use any normal map+support compute skincache without visible seams. Is there really no workaround?

Today support compute skincache doesn’t work at all (no difference between checked or unchecked box), even after restarting. Very strange behavior. Now there is a shadow in the armpit area.

try to verify the engine files first. If it keeps on doing nothing you should probably package a project and send in a bug report.
can’t say I have noticed this, but I removed my main character to work other features, so that’s probably why.

I got back here form google since I still had issues, which in .25.1 are still present.
While here, you can use the node provided above to directly otput a Tangent into the Tangent Output node - off the base skin normal.

Can you see the seams?
Took about 2 hours of fiddling. the mesh has to be specifically made for it.

The seam on the neck is due to texel difference of the high res head vs the texel density of the skin. I’m thinking a manual LOD will correct this in most cases.
High res LOD being only ever applied on cinematic maybe.

If anyone is still using 4.24 the fix is changing line 57 in RecomputeTangentsPerTrianglePass.usf to be

Ret.OriginalOrientation = (W <= 0) ? -1 : 1;

Apparently someone placed a minus in the wrong place inverting the thing.
As for 4.25 and 4.26 The issue is this code doesn’t seem to be working anymore for some reason?

uintDupVertexIndicesLength = DuplicatedIndicesIndices[2 * VertexIndex];
uintDupIndexStart = DuplicatedIndicesIndices[2 * VertexIndex + 1];
for(uintDupIndexOffset = 0; DupIndexOffset < DupVertexIndicesLength; ++DupIndexOffset)
uintDupVertexIndex = DuplicatedIndices[DupIndexStart + DupIndexOffset];
// TangentZ
InterlockedAdd(IntermediateAccumBufferUAV[DupIndex + 0], IntTangentZ.x);
InterlockedAdd(IntermediateAccumBufferUAV[DupIndex + 1], IntTangentZ.y);
InterlockedAdd(IntermediateAccumBufferUAV[DupIndex + 2], IntTangentZ.z);
// TangentX
InterlockedAdd(IntermediateAccumBufferUAV[DupIndex + 3], IntTangentX.x);
InterlockedAdd(IntermediateAccumBufferUAV[DupIndex + 4], IntTangentX.y);
InterlockedAdd(IntermediateAccumBufferUAV[DupIndex + 5], IntTangentX.z);
// Orientation
InterlockedAdd(IntermediateAccumBufferUAV[DupIndex + 6], IntOrientation);

The issue is not in this chunk itself but in something that leads to it and I cant quite tell what’s wrong. If someone could dive into this and figure it out that would be great!

Please. It could show a screenshot of the nodes.

This problem is a nightmare. Why is a person from Epic not commenting on it? The problem has been unsolved for more than 4 years.

As you can see the problem isn’t a problem at all, is just that people don’t know how to work it / it isn’t included in standard tutorials or docs.

You can see the node to use right in the first post.

Instead of connecting it to the normal, plug the tangent into a tangent output node.

Currently (.25) this works well enough even on projects without compute skin cache turned on.

Obviously your model has to have the same tangents/normals on the edges.

Thank you very much for your quick reply. I thought that you had found the solution to this serious problem. The Node no longer solves anything. I have “compute skin cache” enabled because it is an Alembic character animation. The problem is not with the Normal texture. In the image that I show you, only the “Base Color” is connected and the problem persists. Before activating “compute skin cache” it was perfect, but there was instability on the surfaces of the areas with a lot of movement. The solution would be to put hair on the character to cover the mistake. Unfortunately this character is bald. This problem has not been solved for 4 years. And now in 4.25.4 it is more serious than in previous versions.

First, check the model without a material. IF you have a hard edge on a fully rough black material, the issue is the model. Near nothing you do will change it.

You definitely need to add all the correct (clean) maps.
Roughness and Spectacular have a tremendous effect on the seam areas.
Normal maps more obviously so.

You take the normal map (which you have none of in the screenshot) and plug it into the Derive TangentBasis Node. This can be a neutral normal map as well, it just corrects the result.

For Skin you set the material to
Surface - Masked - SubSufrace Profile (and assign a proper one).

Make sure Tangent space normal is checked - should be the default.

Tick Use with: Skeletal mesh, Static Lighting, Morph Targets (and you said alembic? if so Geometry cache).

In the material graph, connect all the proper maps, and as mentioned, derive the Tangent like this

Additionally on the mesh Build settings you need to make sure that Recompute Tangents is set - should be default.
This is NOT the same as checking it within the material under LOD. There is no need to check “recompute tangent” on the skeletal mesh LOD material in .25 or .26. It works as is.

IF you still have issues the fault is either with the textures, or with your model.

Possible solutions are the same as for any seam. Bumping up UV precision (use full or change threshold UV/tangent, and or tick High Precision Tangent.

For Hair I still have Recompute Tangent checked in .26.

BTW, light settings DO NOT matter, but mesh settings do.
on .26 I have Skin Cache Usage specifically set to enabled for all the modular meshes.
Further the Lighting options are a bit more complex - works in tandem with a directional light and is not necessarily going to work for everything.

The directional light:

Oh, and yes in .25.3 transmission was bugged. in .26 it seems to be working fine.

this is a bug in GPUSkinCache.cpp. you need modify the code in the function FGPUSkinCache:: DispatchUpdateSkinTangents:

if (bFullPrecisionUV)
if (GAllowDupedVertsForRecomputeTangents) Shader = ComputeShader11;
else Shader = ComputeShader01;
if (GAllowDupedVertsForRecomputeTangents) Shader = ComputeShader10;
else Shader = ComputeShader00;


if (bFullPrecisionUV)
if (GAllowDupedVertsForRecomputeTangents) Shader = ComputeShader01;
else Shader = ComputeShader11;
if (GAllowDupedVertsForRecomputeTangents) Shader = ComputeShader00;
else Shader = ComputeShader10;

notice:This can only solve the problem caused by uv distribution,This does not work for separate sections


Hey Everybody!

I’ve tried all the solutions listed above and i’m still having those uv seams issues (that i really dont have when the option is of in project settings), does anybody have a solution about that or is it still bugged?

Thanks :slight_smile:

Now that problem in my pocket too…
Tried every answer, nothing helps. I don’t wanna dark glitchy shadows but i also don’t wanna hard edges!
Sombody ELP!

This method works, but all skeletal mesh have only smooth shading, even if you foce mark the edges it still will convert to smooth shading. No one has a proper solution yet?


Seems like they fix it in the UE5 preview 1! (~ ̄▽ ̄)~

And there are some changes, you can choose the vertex color channel on which you want to recompute the tangents <3

Have fun!

Edit: Just for clarify, we have two problems with recompute here:

1 Recompute tangents breaks normals in tangent space, so you will have to use the workaround from @witch-dev.

2 since 4.25 recompute tangents generates visual seams for each UV seams, and there’s no way to fix it from your mesh, that’s an engine bug in 4.25, 4.26 and 4.27, as @bestpeng shows (thanks a lot, I’m working with a source build of 4.27 with your fix)

Epic have solved the second problem, the problem with the first one is knowing how to work recomputing tangents, as @MostHost_LA say.


Isnt that wonderful?
So not only are they missing a channel (because who cares about Alpha?), but now there seems to also be no option to leave the vertex colors alone…

If you wonder why professionals are upset at epic, look no futher.

Obviously this is 3 years after this thread was started so I expect a lot of things have changed with the engine since then, but either way I just wanted to post this as a reminder for myself:

My solution is to go in the Normal texture itself > Compression Settings > select Normalmap (DXT5, BC5 on DX11). You’ll see the color visibly changing due to the new compression and connecting it to the Material now fixes all the seam issues.

Hope this helps/

1 Like