Unity-SpriteAssist icon indicating copy to clipboard operation
Unity-SpriteAssist copied to clipboard

Mesh normals aren't correct

Open MateuszRe opened this issue 3 years ago • 9 comments

Hey again, i noticed that the generated normals arent correct (left is how it looks, right is how it should look for a flat surface): normals

Its caused by the triangles sharing vertices (which is perfectly fine when you dont need to use normals, as it reduces the vert count to minimum), i fixed it on my end by splitting the vertices on the generated mesh using this little method: https://pastebin.com/QqpVQT75 You could make it an optional thing, as it does increase vert count quite drastically (triple the amount of triangles). They can however be welded back together afterwards (but respecting the normals this time), which will still be quite a bit more than the original but that's the choice here if someone wants correct normals. I can provide you with a welding method too, although its not as clean as its part of my much older code base.

MateuszRe avatar Mar 30 '22 06:03 MateuszRe

Thank you for your report!! I will refer to your code and fix the problem. (as a new option like 'Normal: Optimized Normal' or 'Normal: Currect Normal')

sr4dev avatar Apr 01 '22 00:04 sr4dev

Hey, great! So in case you want it, here's the code to weld vertices back together: https://pastebin.com/fSNYiUKf (like i mentioned, its a bit messy, but it works). You need to split them first, then do mesh.RecalculateNormals() and then weld it back together.

Also, Im not sure how far you're interested in developing this tool, but as a brief FYI there are some interesting options there, especially in the area of manipulating the output mesh to make it more defined. Ive added several stuff to better suit the needs of my game, and aside from rotating/scaling the mesh one thats particularily intersting is modifying the vertex 'height' with the use of unity animation curves like so: meshoutput

It doesnt always work perfectly though, as its very reliant on vertex distribution around the edges, if its not dense enough then there might be some glitchy looking results. It would work best, if there was a way to add some spare vertices within the polygon after generating the sprite outline, but before triangulation, sort of a middle ground between what the 'OpaqueMesh' and 'GridMesh' do, im not sure if that's easily doable or not, i had a brief look at the generation code for both of those but it wasnt easy enough to read for me, maybe you'll have a better idea! :)

MateuszRe avatar Apr 01 '22 07:04 MateuszRe

Looks great!

modifying the vertex 'height' with the use of unity animation curves

How about using a height map texture? image This is a height map texture used for the terrain. I think I can apply it on sprite too.

sr4dev avatar Apr 01 '22 15:04 sr4dev

Yeah, a height map would work too! Although the same issue would still apply, it would only be sampled where the vertexes are, so only around the outline of the sprite, to get any more detail we'd need more vertexes added within the polygon.

MateuszRe avatar Apr 01 '22 15:04 MateuszRe

Work in progress image

image

sr4dev avatar Apr 14 '22 09:04 sr4dev

That looks awesome, man, well done! Thank you for the update, Its definitely moving in the right direction!

MateuszRe avatar Apr 14 '22 13:04 MateuszRe

New version updated!

sr4dev avatar Apr 21 '22 07:04 sr4dev

This is awesome, thanks! I've played around with it for a few hours and have some information for you:

  • I noticed you've added the WeldVertices method to MeshUtil but you're never using it, you can call it right after you call SplitVertices, as it can help bring down the vert count by quite a bit after the split (depending on a case)

  • I also noticed the new Opaque Edge Grid Mesh wasnt getting extruded, so I played around with adding that myself. I first just tried using your ExpandMeshThickness method on the combinedMesh in the GetCombinedMesh which worked, but wasn't perfect as it generated faces inside the mesh on the outlines of the grid and the inner outline of the OpaqueWithoutTightGrid part, since the edges between those were not guaranteed to be pairs.

  • So then i tried another approach by splitting the ExpandMeshThickness method into 2 seperate ones, one that generated the side faces and one that generated the backface and offset the vertices, like so: https://pastebin.com/XPH6M76N and then using it like this: https://pastebin.com/pDcV3Ndi (backface+extrude on the combinedMesh, while for the one generating sides i used Opaque mesh). This worked better, as it got rid of the inside faces, although results were still not always perfect, as there were some artifacts (gaps) and also it did not end up resolving the situation completely in a way that would allow for flawless use of heightmaps and such, although it did improve it quite well in some cases, ill show you examples.

  • First the improvement, here on the left is Opaque variant, on the right Opaque Edge Grid Mesh, you can see a 'sunken' area on the Opaque one that's now fixed thanks to the new grid method: Example1

  • As for the reason there might be artifacts present while playing with height manipulation: Example2

The triangulation of the OpaqueWithoutTightGrid part uses less vertices than the Grid mesh, so the faces end up being raised differently between them. This can be mitigated by using smaller grid mesh, which has a good chance of making the gaps less noticeable, but not eliminating them completely: Example3

Im only sharing this as an FYI in case you're interested, not asking you to fix it further, as its definitely good enough for my needs, the gaps wont be noticeable in my use cases (weapons being too small on the screen to notice). Once again, thank you for the amazing tool, its super useful!

MateuszRe avatar Apr 21 '22 20:04 MateuszRe

OK. I'll check this!

sr4dev avatar Apr 26 '22 01:04 sr4dev