Vertex normals and positions split at UV bolder points after displacement map applied

Hey folks,

Still testing displacement maps. This time I am using a mesh with UV and apply a UV-based displacement texture to it. Then I ran into 2 issues:

Issue 1. The vert normals at UV bolders split once applyDisplacementMap got executed:

In the screen capture above, please note the verts I circled in green color. And even I set the displacement maxHeight to 0. You can see the normal are split still.

Issue 2. In some cases, even bolder verts are split and their position been pushed unevenly, generating a gap at UV bolder:

(this is a specific mesh sorry cannt provide a PG for this. But this is the observation.)

I checked all maps. Very sure map are seamless at UV bolders.
This is my PG:

In my PG, I have a function (found on internet, sorry forgot the source) called fixSplitNormals to fix the UV normals split for the verts at same position (a patchy solution for issue 1). But for issue 2, still don’t have a neat solution for it.

So just wondering, in general are there better ways to handle issue 1 and 2?

Many thanks

cc @sebavan @Evgeni_Popov @PatrickRyan who know a bunch of rendering hacks

@tawibox, are you using a glTF file for your mesh? If so, all of the UV border vertices will not be welded in the file. This is a part of the glTF specification to unweld any vertices at UV borders as it’s cheaper which is the goal of the format. This means that if you are using texture-based displacement you need to be sure that the displacement texture respects your UV borders and offsets all edge vertices in the same way. This can be accomplished by projecting your texture into UV space in a DCC tool (Blender, Substance Painter, or similar) and then exporting the texture. This makes procedural displacement trickier as you would need to do that projection in real time to make sure you have the same values along every UV seam.

The displacement map method recomputes the new normals by using the face normals, so it’s expected to have different normals for a vertex if this vertex is not shared by faces but each face has its own set of vertices instead. Applying a post processing is the way to smooth the normals, as you did.

Regarding your second problem, it’s hard to say, maybe you have multiple vertices at the same location that don’t have the exact same uvs?

@PatrickRyan Thanks for the response!

I am actually using a .obj file in my test. But still got unweld verts along UV seams.
So not sure if there is a file format more “displacement friendly” in babylonjs?

Also the test texture I am using are exported from substance painter with edge bleeding applied. I checked the texture before applying them in babylonjs they pretty sure seamless in across UV seams.

Many thanks!

@Evgeni_Popov Thanks for the response!

Ok in that case, I can live with my post processing approach for issue 1 for now.

For issue 2, I checked my mesh they are quite clean. I don’t think the case you mentioned applies to my example.

Another possible reason I suspected (same as @PatrickRyan mentioned above), is that if the textures are not seamless across UV bolders, it might cause this uneven displacement. But just confirmed this should not be the case either. I created bunch of very clean map from substance painter (even with edge bleeding on), still see the vert position split.

I do have another post processing solution is: a) provide a dictionary that lists all border verts which supposed to at the same position in sets. b) And use another function to force those verts to move to the same / averaged position. c) then use fixSplitNormals to fix their normals. With this approach, I can manually “weld” those gap verts after displacement.

Sounds not ideal but at least this should make the render look ok :laughing:

Many thanks!!