Hello polycounters! This is the premise:
I'm trying this new workflow for medium/large props. In short, what I'm trying to do is bake the least amount of normal information from the highpoly to the lowpoly, and then stretch/duplicate/mirror the various pieces to form the desired mesh. I'm using separate id channels for normals and for tileable materials, sort of like the trimsheet workflow.
At first I didn't notice any problems, then I started seeing these faint seams at steep light angles:
Below are the modules with which I built this specific piece of door (left highlighted is lowpoly, left non-highlighted is highpoly, right is assembled mesh)
I thought the error might be caused by the baker, but I checked the bake normal map file and all faces at the converging point have the same RGB color value (#8080ff).
Does anyone have an idea on what might be causing this error, and how it could be fixed?
Replies
(thanks for the interest btw!)
the FBX contains 3 meshes. Highpoly, lowpoly, and the assembled final mesh. I baked the hp on the lp with a cage, then I assembled the mesh by stretching/duplicating the pieces. Here's the seam visible in substance painter with 0.3 roughness (when rendered in UE4 it's a bit more evident than in SP but this was quicker)
This is the result when I try importing the same test file I sent you into UE4 with 'import normals and tangents'.
I have uploaded my baked map and the test file, could you try importing these into ue4 on your end?
https://drive.google.com/open?id=1tpZpfymqIP93kOXunFl1HE47-nK8LuYZ
I'm thinking maybe it's something in my 3d suite export options, or my baker?
Also, I had to disable mipmaps on your texture because it was showing another error too. The uv islands are too close to each other so the other parts of the texture were bleeding in causing lines (not seams). This error looks different, you will see once you fixed the seam. So I would recommend leaving more space between them.
This is what the normal map compression does:
1. From these tests, I would assume that the input normal map gets pushed into 8 bit first - this is theoretical, I'm not entirely sure, but it looks like this happens.
2. Remove blue channel - Surely
3. Stretch red and green channel out to 1,-1 range - Surely
4. Derive the new blue channel from the stretched red and green channel - Surely
5. Remove alpha channel - Surely
We can confirm step 2-3-4 and 5 by putting random things into the alpha and blue channel, and we still get a correct normal map in Unreal, plus we can see that a correct blue channel appears in the normal map compressed texture when viewing it in the texture preview. The 1,-1 range can be confirmed by feeding the red or green channel into an "if" and comparing it with negative values. Removed alpha channel is obvious.
I'm baffled by all this, but having a workaround is still a huge thing for me!
Thanks again @Obscura !
Ok, your last observation is strange and confusing, I have no idea how could that be, but at least it can be solved with a fairly simple fix.
Can you please try the same thing with a 8 bit bake, and see if the post-adjustment value becomes constant, or still changes with the different meshes?
The workflow between these meshes is entirely the same, these seams were more evident at the intersection with their mirrored side though, I don't know if that might be relevant.
I will without a doubt pay more attention now that I know what to look for. If I find anything new I'll be sure to report back here!
I have one more idea to try, but after all of these, I doubt that it will do much. Can you try enabling "high precision tangent basis" and "full precision uvs" on the meshes and see if it makes the value constant?
Neither did anything. Never found a valid use for these options...
Its a precision issue of the normal map. the Flat area of the normal is not 128,128,255 but fluctuates between that and 127,127,255
Your solution did not work for me as add/subtracting didn't seem to do anything.
What end up working for me was flattening the normal with a value of 2 (1 flattens the normal value above inverts it) that inverted normal then goes through a saturate node to clamp it. Only caveat is normals are inverted now - multiplying the normal with a 1,-1,1 constant vector inverts the normal but brings the seams back.
Maybe if I bake my normals inverted and do the above will fix that? (flipping green channel did not work either they still appeared inverted).
Here are some test results.