Unity glTFast package is now available

Yeah this is a real oddity but is it not down to the gltf format itself separating meshes by material?
If the Khronos package can combine them then is that supported for runtime loading and is it not a performance issue if used there?

Yes, but generally if we want to instantiate a specific mesh by name then it’s strange because there may be N meshes with the same name in the gltf file. There’s clearly a way to access the data and understand their relationship/material mapping in order to merge them, but it’s not clear at a glance how to do so. Feels inelegant overall, but it may just be our use-case making me biased. I’m happy to work around it, just not sure how to do so yet.

I agree that glTFast should do a better job of preserving sub-meshes and since this comes up on a regular basis, it’s high on my wish list as well.

But to set the expectation right, glTF’s mesh-primitive concept allows for much more freedom than Unity’s Mesh (e.g. different vertex buffer layouts or even different topology). In those cases glTFast (or any glTF importer really) will always split up glTF primitives into Unity Meshes.

2 Likes

Hi, I was able to SaveToFileAndDispose the gltf. My final project is to send mesh over WebRTC. Is there a posibility to read the gltf data as a string or bytes ? I’m using RTCDataChannel to send the file.
Thanks in advance.
Mycode

async void GltfExport()
    {
        // Example of gathering GameObjects to be exported (recursively)
        var rootLevelNodes = GameObject.FindGameObjectsWithTag("ExportMe");

        // ExportSettings provides generic export settings
        var exportSettings = new ExportSettings
        {
            Format = GltfFormat.Binary,
            FileConflictResolution = FileConflictResolution.Overwrite,
            // Enable Draco compression
            Compression = Compression.Draco,
            // Tweak the Draco compression settings
            DracoSettings = new DracoExportSettings
            {
                positionQuantization = 12
            }
        };

        // GameObjectExport lets you create glTFs from GameObject hierarchies
        var export = new GameObjectExport(exportSettings);

        // Add a scene
        export.AddScene(rootLevelNodes);

        // Async glTF export
        bool success = await export.SaveToFileAndDispose("C:/AumentaSolutions/_DEMOS/DEMO_WebRTC/glTFast/test.gltf");

        if (!success)
        {
            Debug.LogError("Something went wrong exporting a glTF");
        }

        if (success)
        {
            Debug.Log("exporting a glTF : " + export.ToString().Length);
            byte[] fileBytes = System.Text.Encoding.UTF8.GetBytes(export.ToString()); // Trying to read export as byte array
            string flieString = export.ToString(); // Trying to read export as string
            dataChannel.Send(flieString); // Get "GLTFast.Export.GameObjectExport", not the data file
        }
    }

SOLVED : used SaveToStreamAndDispose

Is it possible to get extra data when importing .glb format?

Using a custom addon, my nodes are not casting to GLTFast.Newtonsoft.Schema.Node

var node = gltf.Nodes[(int)nodeIndex] as GLTFast.Newtonsoft.Schema.Node;
var extras = node?.extras;
if ( extras == null )
return;```

hello,
is there a setting or method to export shadowmaps with this package? it appears that shadowmaps are not exported with the asset when exporting to glb.
Or is there a better way to get the shadow maps from out of unity and into a threejs environment? any advice is greatly appreciated!

Your exporter does not properly format .GLB files, by the way. e.g. I saved a scene with various capsules spawned in it. The .GLB saved from this, when converted to text, started with:

{"asset":{"version":"2.0","generator": ...

This is the incorrect header for a .GLB file. You need to have the first 4 ASCII characters match “glTF” which you implement as a proper check in the importer. Specifically, when the byte array being read from the file matches public const uint GltfBinaryMagic = 0x46546c67 (which should be the ascii “glTF”, converted to hex).

This is what a valid .GLB header looks like, which glTFast successfully imports:

glTFê,JSON{"asset":{"generator": ...

I spent days wondering why your .GLB importer wasn’t working, but it was working. The issue was that your .GLB exporter isn’t correctly exporting the files.

This is really awesome. Thanks a ton!

We just switched from UnityGLTF to Unity glTFast. Doing so shaved an entire second off the loading times of our models in game.

2 Likes

Soooo… any update on this? Your own importer cannot import objects that your own exporter exported, because of the reason above.

Do you mind explaining me your steps to reproduce? Either your export code or which menu item exactly you clicked.

Good idea! I’ll try to explain a bit more precisely, as I am not allowed to share the code:

I had an empty scene where glTFast was installed, and I had a capsule with the “ExportMe” tag on it, then I used the documentation’s SimpleExport() function to export the capsule.glb to the persistent data path.

I then referenced that same capsule.glb using LoadGltfBinaryFromMemory() and that’s where the import failed. I traced this down to capsule.glb not satisfying GltfGlobals.IsGltfBinary(bytes). I opened capsule.glb and, as referenced earlier, it lacks the ASCII “glTF” which needs to be appended to the front of the file. If I use this same function to load, for example, a .glb exported from Blender, I can successfully do this import. The objects being exported using SimpleExport() do not prepend the .glb file with the ASCII magic binary value.

The SimpleExport example was a good starting point. I wish you didn’t stop reading the documentation at that point, because below it shows you can pass an ExportSettings instance as parameter to GameObjectExport. The Format property is the one you need to set:

// ExportSettings provides generic export settings
var exportSettings = new ExportSettings
{
    Format = GltfFormat.Binary
}

Setting the destination filename’s extension to .glb alone doesn’t do the trick.

hth

2 Likes

Thanks for this information! I cannot confirm, yet, whether this is the trick that will work, but I will have to find out. I definitely read 100% of this documentation. This part was not at all clear to me when reading the docs. I wish I had a good suggestion for how to make it clearer, but now I know where to look amidst all of this!

Hi is there no scale factor on import like with other formats? It means I can end up with a scene node at 0.01 scale when I just want everything below that node to be scaled up on import instead.

In order to scale the glTF instance you should scale the parent Transform that you provide for instantiation. The GameObject representing the scene (in case one gets added; that’s not necessarily the case) will have a uniform scale of 1 and all the nodes their original local transform.

hth

Well you are right you can do that of course, it is not a deal breaker.
But surely the reason for the scale in something like fbx import is so that you begin with something at the right scale when no scaling is applied to the root transform (1x1x1). If something is modelled too small you can then scale it during import instead of having to always draw it .5 scale or something. You can manually modify the transform tree post import, but I guess it makes it easier.

You should address the scaling problem in the source application, as this is where the issue is caused in the first place. I’m not necessarily saying that import scale isn’t useful, but frankly it’s a crutch for bad workflows.

1 Like

I kind of agree with @LaneFox , but not all developers are in (direct) control of the assets, so @andyz 's got a point.
Two thoughts:

  1. glTF defines its unit as meters. Sticking with that should prevent the need for additional scaling.
  2. To avoid repetitive re-scale of assets, you can create a correctly scaled Prefab as a workaround.

Yes it is avoidable.
On another subject - being able to export to glb/gltf from the editor is really great to play with!

It seems exporting with compression options has to be done in code currently, which may have some documentation/code-comment mistakes as just mentions replacing files!: Enum Compression | Unity glTFast | 6.6.0 (unity3d.com)

Can you use KHR_mesh_quantization for glb export? (which seems like a simplified built-in version of Draco in some ways - Draco has a lot of options!)