UnityGLTF icon indicating copy to clipboard operation
UnityGLTF copied to clipboard

Vertex reordering after import

Open Phlegmati opened this issue 3 months ago • 2 comments

Describe the bug 💬

How to disable vertex re-ordering on import?

similar to on fbx import settings:

Image

Why?

I tried to bake additional vertices information (for a cloth simulation, a float weight 0 - 1 ) inside another uv-map (channel 2) for my model. I exported out of blender for unity. Once as .fbx and once as .glb

Image

When I imported my model and ran my script to extract the value per vertex, both models were simulating wrong.

using UnityEngine;

[RequireComponent(typeof(Cloth))]
[RequireComponent(typeof(SkinnedMeshRenderer))]
public class CreateClothFromUVData : MonoBehaviour
{

    public float maxDistDynamic = 0.1f;

    public void Start()
    {
        var cloth = GetComponent<Cloth>();
        var smr = GetComponent<SkinnedMeshRenderer>();
        var mesh = smr.sharedMesh;

        if (!mesh.isReadable)
        {
            Debug.LogError("Mesh is not readable.");
            return;
        }

        Vector3[] renderVertices = mesh.vertices;
        Vector2[] uv3 = mesh.uv3;
        ClothSkinningCoefficient[] coefficients = cloth.coefficients;

        if (uv3.Length == 0)
        {
            uv3 = mesh.uv2;
        }

        if (uv3 == null || uv3.Length != renderVertices.Length)
        {
            Debug.LogError("UV3 channel missing or length mismatch with vertices.");
            return;
        }

        for (int i = 0; i < coefficients.Length; i++)
        {
            float weight = uv3[i].x;
            coefficients[i].maxDistance = maxDistDynamic * weight;
        }

        cloth.coefficients = coefficients;
    }
}

I took a deeper look and saw, that unity (or the import plugins) reordered the vertices (for better performance I guess) on import. But then my custom created uv channel did not correctly map to vertex indices anymore (textures do btw, I don't know why my channels did not get remapped like normal map too..)

So I disabled "Vertex Order" on fbx import settings and it behaved correctly for the fbx model.

Image

UnityGLTF is missing this option, so it still behaves wrong.

Image

Fixes:

Is there any chance you will add this Option? - Or at least: Could anyone show me the spot to where to patch it or how to get the right post-import index-mapping-dictionary - or something else? I took a look inside the source but could not find the script where it reorders the vertices.

Thanks in advance!

Steps to reproduce 🔢

  1. Create a new Unity 6.0 Project, Install UnityGLTF and DracoMesh Compression as package:
{
  "dependencies": {
    ...
    "com.unity.cloud.draco": "5.1.8",
    "org.khronos.unitygltf": "https://github.com/KhronosGroup/UnityGLTF.git"
    ...
  }
}
  1. Download the unity package: unitygltfissue.zip
  2. Import the Package
  3. Open Scene, see for yourself

Optionally you can import the meshes (.glb/.fbx) yourself

Files to reproduce the issue ♻

No response

Editor Version 🎲

6000.0

Render Pipeline and version

URP/HDR/SRP

UnityGLTF Version

2.17

Operating System 👩‍💻

Windows

When does this problem happen?

  • [x] Editor Import
  • [x] Runtime Import
  • [ ] Editor Export
  • [ ] Runtime Export

Additional Info 📜

No response

Validations 🩹

Phlegmati avatar Sep 22 '25 12:09 Phlegmati

Hm, we're not doing this kind of reordering/optimization on import by default...

Can you explain how I can go from the blend file you attached to an exported GLB that has the correct data, or attach an exported GLB that already has correct vertex colors? The one in your unitypackage does have "COLOR_0" and "COLOR_1" but both seem to be just white.

In other words: I believe this is not a UnityGLTF issue but an issue on how you're creating / exporting the GLB, the GLB does not have the same vertex color data as the FBX at the moment.

You can validate e.g. in https://viewer.needle.tools, drop your file and then choose Data View Mode = Vertex Color:

Image
File Type Screenshot
FBX FBX Screenshot
GLB GLB Screenshot

hybridherbst avatar Sep 22 '25 16:09 hybridherbst

Hey @hybridherbst thank you for the fast reply!

Yeah sorry for the misleading, but it is not about vertex colors. The fbx just tends to create vertex colors, if no material is applied - out of my attribute I baked in.

Let me be clear:

I created another UVMap, with an float attribute "weight" per vertex. But instead of a texture UVMap, which points to an image texture with 16byte float (4x32bit per color channel rgba), I bake my greyscale value directly in the 8 Byte per Vertex.

As you can see in Unity, both UVMaps are also recognized and imported. I clicked on the Mesh inside the Model Prefab to show the UV-Data, where UV0 is for texture mapping (normal, color, height etc.) and UV1 is my custom created UVMap:

Image

So in both files (.fbx and .glb), my UVMap and values are there, with the exported order of vertices.

My code in blender is a pretty simple mapping of vertices[index] = weight. And in Unity: weight = vertices[index]. This should work, if the order of the vertices is not changed during import. - And it does:

If I unselect Optimization > Vertex Order in the fbx import settings, everything works as expected (but this is missing for glb).

So that is why

I assumed Khronos does also reorder the vertices for optimization and could toggle it off?

But sure, I will also take a deeper in look in the export pipeline of blender, but somehow I doubt that the export rearranges anything - it does for sure with draco Mesh Compression but that is predictable and not the scope of this topic.

Phlegmati avatar Sep 22 '25 17:09 Phlegmati