vpenades / SharpGLTF

glTF reader and writer for .NET Standard
MIT License
467 stars 75 forks source link

Vertices sharing in sharp edged geometry #59

Closed berry4u closed 4 years ago

berry4u commented 4 years ago

I noticed the optimization process leads to merge vertices even among meshes with different normals (i.e. a cube is shrinked in 8 vertices and 12 triangles - instead of typical 24 vertices and 12 triangles taking into account the three different normals in each corner). Tho this is useful to shrink file dimension it could be time consuming for correct rendering because of vertices splitting to differentiate normals when geometry is sharp edged (i.e. architecure, low poly, etc. ). Is there an option to preserve vertices or share them only on planar surfaces?

Thank you

vpenades commented 4 years ago

Are you setting the vertex normals when adding a new vertex to the mesh?

If you want to split by normal, you need to use VertexPositionNormal or VertexPositionNormalTangent instead of plan VertexPosition

The vertex equality is evaluated as a whole so, as you say, a position with two different normals will be kept as two separate normals.

berry4u commented 4 years ago

Made some experiment finding that in most cases the file is on average almost 4 time larger due not only to increased number of vertices but also to normal data overload. To me, it could be very useful to allow saving only VertexPosition but choosing as option whether sharing or not vertices among triangles. Moreover in most cases normals are even recalculated in loading phase (i.e. for specific smoothing) so that saving them into file could be not efficient.

vpenades commented 4 years ago

Well... glTF specification states that a mesh without normals should be rendered with flat faces, although in practice, some engines do interpret it as smooth shaded. But certainly, a mesh without normals and splitted vertices to force seams is way out of the specification. Keep in mind that by not following the standard your duplicated vertices may be lost whenever you pass your glTFs through any optimization.

In fact, if file size is a concern to you, you can try using the glTF Pipeline to try to compress the model as much as possible, for which you can choose Draco compression, or the quantized vertex attributes extensions, that will quantize the normals to use just 3 bytes, and will do a lot more tricks to reduce the file size.

Having said that, it could be possible to create a mesh with normals to keep track of the splitting vertices, and then use this base mesh to copy only the attributes you need to a final mesh without normals.

In any case, using the approach you suggest is weak, because any present or future glTF optimization might automatically weld the duplicated vertices, and will render your glTF models essentially non standard.

berry4u commented 4 years ago

vpenades, you convinced me definitively! You are right, any out of specification would be lost in an unattended optimization process. Thank you for your time.