The new glTF import supported in 4.19 preview is awesome. [Experimentation]

@ I/my company is looking into runtime glTF support for Unreal AR sessions - I’m pretty familar with the code you’ve written (I’ve studied the source code extensively) - I’m curious what your opinion/thoughts are on the idea of making this plugin free of “editor” dependencies so that a cooked/deployed Unreal project, on-device, could process glTFs at runtime? This would open up a whole world of possibility in the consumer AR space.

I’ve found ways to do this that take a different approach than your plugin, but I like your plugin’s approach more than my own. Do you have any thoughts on this (freeing the plugin from editor dependencies)? Is your approach even do-able at runtime or are there landmines you’re aware of that would prevent this usage?

Specifically, we approached this use the ProcedualMeshComponent instead of creating static meshes, which worries me a bit, since that is experimental as well. Also, I like the way you dealt with loading Textures, although this is the most dependent on the Editor libs. I had considered simply copying out snippets of source code into my plugin, and de-editorizing them, but theres a deep rabbit hole there that I’m concerned about in making so many copies of engine code. Have any advice on what you think a proper approach to this would be?

Well, glTF is designed as a runtime delivery format (it is optimized for use at runtime, not edit time) so I suspect that eventually runtime loading of .gltf and .glb files outside of the cooked game data will be supported. I mean that’s the whole point of glTF, so why implement anything if you aren’t going to implement that?

Point of glTF is “transmission format”. There’s nothing about “runtime” or “edit time”. Unreal engine is designed to load assets prepared at edit time. Doing correct import at runtime will require lots of editor modules being pushed into runtime, for example - MeshUtilities, ShaderCompiler, Jpeg and Png decoders etc. And at the same time, there’s no point for loading glTF files by UE4 at runtime. Really, no point - unless you want to make “another one glTF viewer”, which is not the point of doing huge changes in the engine.

Hi @,
I have exported a basic mesh from Blender using KronosGroup Blender glTF 2.0 Exporter
However I can’t reproduce the way you imported you gltf file into Unreal Engine like on your initial GIF.
I’m on the 4.20.2 Release and it doesn’t seem to support GLTF file on import.
Do I have to activate some hidden option or something to import glTF files ?
Thank you

Did you enable glTF plugin?

Are you talking about c4g.io’ plugin ? GitHub - code4game/glTFForUE4: Import glTF 2.0 in Unreal Engine
Is this related to the original poster experimentation ? I don’t see him talking about installing any plugin when importing a gltf file.
It seems to be supported natively from 4.19 according to its post.
Anyway the c4g plugin isn’t available for 4.20 and it’s not on the marketplace, I’m not sure if this is just a POC or actively maintained.

Of course no. I never tried that third-party plugin, so I’m talking about built-in one (and this topic is about built-in plugin).
The plugin is in “experimental” stage, and all such engine features are disabled by default. You should go to the settings, find glTF plugin and enable it. After that, .gltf files will be supported by standard “Import” option.

Ok found it in the Importers plugin in the engine
Thank you

OF COURSE there is a point to loading glTF at runtime… Not everyone using Unreal is working on a game.

The FIRST SENTENCE in the specification: “The GL Transmission Format (glTF) is an API-neutral runtime asset delivery format.

This doesn’t mean “you should load and parse glTF files at runtime” :slight_smile: This means that data structures of this format are suitable for being rendered at runtime without further processing, that’s why it is a “runtime format”. However for a complex engine like Unreal, you’d either need custom rendering code (which won’t conflict with main renderer), or you still need data processing / conversion into engine’s renderable structures. This conversion is done in Developer/MeshUtilities module, which is not a runtime one.

Also, things you mentioned are not a point for doing loading at runtime anyway.

There are many good reasons to load geometry at runtime. I have hundreds of millions of CAD models that I need to make available in a viewer at any time. I need that viewer to have functionality that is relatively easy to implement in a game engine, and impossible for the CAD software vendor to implement, despite offering them tens of millions of dollars to do so.

This is a fully valid and much-more-common-than-you-think situation. Game engines are the only reasonable way forward.

GlTF 2.0 does not allow custom shaders to be included, so models loaded from glTF use a standard/default shader in the engine that uses material properties defined in the glTF model. This does not preclude loading at runtime. I’ve reverse engineered and implemented readers for the proprietary CAD format that we use, which is not supported by any commercially available CAD importing tool, so that doesn’t preclude runtime loading, either. I can convert our CAD models into glTF in an offline process that runs at the time the model is put back into source control quite rapidly, and optimize the draw call count (all the way down to 1 draw call per part instance and beyond) while doing it, so runtime performance of these models is not a problem.

I am doing the things that you are saying can’t or shouldn’t be done, except loading glTF at runtime in Unreal. I DO NOT want to convert each CAD model to several different engine-native asset formats each time a new part is drafted or modified. I want to either implement a native CAD asset reader for each engine (which is usually slower than loading glTF at runtime) or convert the CAD assets to glTF once, then use the glTF assets in each engine at runtime. Right now, Unreal is the only reason I can’t just dictate that glTF be used everywhere. All other game engines in use at my employer can do it, and we are using those engines to do it. Not every team wants to use those other engines, though, some want to use Unreal.

Just adding this is a highly anticipated pipeline for us. The fbx importer code has a lot of legacy and is generally a mess. Combined with the lack of documentation on the sdk, it’s very difficult to modify or extend. Here’s hoping for predictable joint orients and usable coordinate space conversion for skeletal meshes.:slight_smile:

Not sure where to post this, but it seems that Mozilla is making some effort to improve the gltf support in Blender, which is great news for everyone who wants to break free from the shackles of Autodesk:

You won’t break free from the “shackles” of Autodesk because people still going to use Maya/MAX which support FBX export natively and most of glTF exporters are not as polished as desired (especially when it comes to exporting skinned/animated meshes). When all 3D apps support glTF feature-complete export/import, then perhaps we can talk about dropping FBX for good.

I just test my plugin by official sample models. GitHub - KhronosGroup/glTF-Sample-Models: glTF Sample Models

You know that I don’t have enough time and models to test my plugin, I just try to ensure most of official’s models are correct when imported into UE4 by my plugin.
I am glad that you let me know if you found a glTF model has any error that is imported by my plugin.

This is imported by my plugin glTF For UE4. It is free and open source.

You can export models from Unreal and then try to import them back :slight_smile:

Did anyone manage to import gltf animations from blender? i cannot, ive used the blender option embed buffers (the .bin file) into gltf but when i import in unreal there is only the mesh, no skeleton no animation nothing.

UE4 supports only static mesh import from glTF format.

Has anyone used this importer on OS X? I’m running 4.21.2 on High Sierra, and UE4 just crashes any time I attempt to import any of the glTF 2.0 models from the KhronosGroup sample models repo.

This was the crash report for SimpleMeshes.gltf:


Assertion failed: (Index >= 0) & (Index < ArrayNum) [File:/Users/build/Build/++UE4/Sync/Engine/Source/Runtime/Core/Public/Containers/Array.h] [Line: 611] Array index out of bounds: 0 from an array of size 0

FGenericPlatformMisc::RaiseException(unsigned int) Address = 0x1015a2f2b (filename not found) [in UE4Editor-Core.dylib]
FMacErrorOutputDevice::Serialize(wchar_t const*, ELogVerbosity::Type, FName const&) Address = 0x101701524 (filename not found) [in UE4Editor-Core.dylib]
FOutputDevice::LogfImpl(wchar_t const*, ...) Address = 0x101851730 (filename not found) [in UE4Editor-Core.dylib]
FDebug::AssertFailed(char const*, char const*, int, wchar_t const*, ...) Address = 0x101765e4e (filename not found) [in UE4Editor-Core.dylib]
ImportStaticMesh(GLTF::FAsset const&, TArray<UMaterial*, FDefaultAllocator> const&, UObject*, FName, EObjectFlags, unsigned int) Address = 0x167916177 (filename not found) [in UE4Editor-GLTFImporter.dylib]
ImportStaticMeshes(GLTF::FAsset const&, TArray<UMaterial*, FDefaultAllocator> const&, UObject*, FName, EObjectFlags) Address = 0x16791b89c (filename not found) [in UE4Editor-GLTFImporter.dylib]
ImportMeshesAndMaterialsFromJSON(FArchive*, FString const&, UObject*, FName, EObjectFlags, FFeedbackContext*, TArray<unsigned char, FDefaultAllocator>) Address = 0x1678ff41f (filename not found) [in UE4Editor-GLTFImporter.dylib]
UGLTFImportFactory::FactoryCreateFile(UClass*, UObject*, FName, EObjectFlags, FString const&, wchar_t const*, FFeedbackContext*, bool&) Address = 0x1678fea47 (filename not found) [in UE4Editor-GLTFImporter.dylib]
UFactory::ImportObject(UClass*, UObject*, FName, EObjectFlags, FString const&, wchar_t const*, bool&) Address = 0x10a7d38e9 (filename not found) [in UE4Editor-UnrealEd.dylib]
UAssetToolsImpl::ImportAssetsInternal(TArray<FString, FDefaultAllocator> const&, FString const&, TArray<TTuple<FString, FString>, FDefaultAllocator>*, FAssetImportParams const&) const Address = 0x11e0d2e21 (filename not found) [in UE4Editor-AssetTools.dylib]
non-virtual thunk to UAssetToolsImpl::ImportAssets(TArray<FString, FDefaultAllocator> const&, FString const&, UFactory*, bool, TArray<TTuple<FString, FString>, FDefaultAllocator>*) const Address = 0x11e0e00a8 (filename not found) [in UE4Editor-AssetTools.dylib]
SAssetView::OnDrop(FGeometry const&, FDragDropEvent const&) Address = 0x11c14395b (filename not found) [in UE4Editor-ContentBrowser.dylib]
FSlateApplication::RoutePointerUpEvent(FWidgetPath&, FPointerEvent&) Address = 0x108a34ecc (filename not found) [in UE4Editor-Slate.dylib]
FSlateApplication::ProcessMouseButtonUpEvent(FPointerEvent&) Address = 0x1089d79e7 (filename not found) [in UE4Editor-Slate.dylib]
FSlateApplication::OnDragDrop(TSharedPtr<FGenericWindow, (ESPMode)0> const&) Address = 0x108a4b9a4 (filename not found) [in UE4Editor-Slate.dylib]
FMacApplication::ProcessEvent(FDeferredMacEvent const&) Address = 0x1089308e1 (filename not found) [in UE4Editor-ApplicationCore.dylib]
FMacApplication::ProcessDeferredEvents(float) Address = 0x10892f14f (filename not found) [in UE4Editor-ApplicationCore.dylib]
FSlateApplication::TickPlatform(float) Address = 0x108a047c2 (filename not found) [in UE4Editor-Slate.dylib]
FSlateApplication::Tick(ESlateTickType) Address = 0x108a03d70 (filename not found) [in UE4Editor-Slate.dylib]
FEngineLoop::Tick() Address = 0x101441e52 (filename not found) [in UE4Editor]
GuardedMain(wchar_t const*) Address = 0x10144a478 (filename not found) [in UE4Editor]
-[UE4AppDelegate runGameThread:] Address = 0x101457880 (filename not found) [in UE4Editor]
-[FCocoaGameThread main] Address = 0x1016ffe67 (filename not found) [in UE4Editor-Core.dylib]
Unknown() Address = 0x7fff2b6d0148 (filename not found) [in Foundation]
_pthread_body Address = 0x7fff51891661 (filename not found) [in libsystem_pthread.dylib]
_pthread_body Address = 0x7fff5189150d (filename not found) [in libsystem_pthread.dylib]
thread_start Address = 0x7fff51890bf9 (filename not found) [in libsystem_pthread.dylib]