GLTF lacking DOOM 3 custom attributes on export, missing functionality?

Hi! I’ve been experimenting with creating content for DOOM 3 using Omniverse, and I’m not sure if I’m missing something, or if functionality is lacking altogether in Omniverse Create.

A source port of DOOM 3 BFG EDITION gained gltf/glb functionality for in-game maps and you can see the tutorial here for creating maps in Blender, but it uses custom attributes defined in Blender to instruct the idTech 4 engine how to render objects and entities.

I thought similar functionality would exist in Create using the “Add Attribute” function to add a string attribute to an entity, but it does not seem like this is exported in the resulting .gltf file.

The GLTF file for a barebones DOOM 3 map exported from Blender looks like this:

{
    "asset" : {
        "generator" : "Khronos glTF Blender I/O v3.4.50",
        "version" : "2.0"
    },
    "scene" : 0,
    "scenes" : [
        {
            "name" : "Scene",
            "nodes" : [
                0,
                1,
                2,
                3
            ]
        }
    ],
    "nodes" : [
        {
            "extras" : {
                "classname" : "light",
                "light" : "500"
            },
            "name" : "light",
            "translation" : [
                0,
                128,
                0
            ]
        },
        {
            "extras" : {
                "classname" : "info_player_start"
            },
            "name" : "info_player_spawn_0",
            "scale" : [
                32,
                64,
                32
            ],
            "translation" : [
                0,
                64,
                0
            ]
        },
        {
            "extras" : {
                "classname" : "worldspawn"
            },
            "name" : "worldspawn"
        },
        {
            "mesh" : 0,
            "name" : "worldspawn.cube",
            "scale" : [
                1024,
                1024,
                1024
            ]
        }
    ],
    "meshes" : [
        {
            "name" : "Cube.001",
            "primitives" : [
                {
                    "attributes" : {
                        "POSITION" : 0,
                        "TEXCOORD_0" : 1,
                        "NORMAL" : 2
                    },
                    "indices" : 3
                }
            ]
        }
    ],
    "accessors" : [
        {
            "bufferView" : 0,
            "componentType" : 5126,
            "count" : 24,
            "max" : [
                0.5,
                1,
                0.5
            ],
            "min" : [
                -0.5,
                0,
                -0.5
            ],
            "type" : "VEC3"
        },
        {
            "bufferView" : 1,
            "componentType" : 5126,
            "count" : 24,
            "type" : "VEC2"
        },
        {
            "bufferView" : 2,
            "componentType" : 5126,
            "count" : 24,
            "type" : "VEC3"
        },
        {
            "bufferView" : 3,
            "componentType" : 5123,
            "count" : 36,
            "type" : "SCALAR"
        }
    ],
    "bufferViews" : [
        {
            "buffer" : 0,
            "byteLength" : 288,
            "byteOffset" : 0,
            "target" : 34962
        },
        {
            "buffer" : 0,
            "byteLength" : 192,
            "byteOffset" : 288,
            "target" : 34962
        },
        {
            "buffer" : 0,
            "byteLength" : 288,
            "byteOffset" : 480,
            "target" : 34962
        },
        {
            "buffer" : 0,
            "byteLength" : 72,
            "byteOffset" : 768,
            "target" : 34963
        }
    ],
    "buffers" : [
        {
            "byteLength" : 840,
            "uri" : "data:application/octet-stream;base64,AAAAvwAAAAAAAAA/AAAAvwAAAAAAAAA/AAAAvwAAAAAAAAA/AAAAvwAAgD8AAAA/AAAAvwAAgD8AAAA/AAAAvwAAgD8AAAA/AAAAvwAAAAAAAAC/AAAAvwAAAAAAAAC/AAAAvwAAAAAAAAC/AAAAvwAAgD8AAAC/AAAAvwAAgD8AAAC/AAAAvwAAgD8AAAC/AAAAPwAAAAAAAAA/AAAAPwAAAAAAAAA/AAAAPwAAAAAAAAA/AAAAPwAAgD8AAAA/AAAAPwAAgD8AAAA/AAAAPwAAgD8AAAA/AAAAPwAAAAAAAAC/AAAAPwAAAAAAAAC/AAAAPwAAAAAAAAC/AAAAPwAAgD8AAAC/AAAAPwAAgD8AAAC/AAAAPwAAgD8AAAC/AAAAPgAAgD4AAMA+AAAAAAAAwD4AAIA/AAAgPwAAAAAAACA/AACAPwAAYD8AAIA+AAAAPgAAAD8AAMA+AABAPwAAwD4AAEA/AAAgPwAAQD8AACA/AABAPwAAYD8AAAA/AADAPgAAgD4AAMA+AACAPgAAwD4AAIA+AAAgPwAAgD4AACA/AACAPgAAID8AAIA+AADAPgAAAD8AAMA+AAAAPwAAwD4AAAA/AAAgPwAAAD8AACA/AAAAPwAAID8AAAA/AAAAAAAAgD8AAACAAAAAAAAAAAAAAIC/AACAPwAAAAAAAACAAAAAAAAAAAAAAIC/AACAPwAAAAAAAACAAAAAAAAAgL8AAACAAAAAAAAAgD8AAACAAAAAAAAAAAAAAIA/AACAPwAAAAAAAACAAAAAAAAAAAAAAIA/AACAPwAAAAAAAACAAAAAAAAAgL8AAACAAACAvwAAAAAAAACAAAAAAAAAAAAAAIC/AAAAAAAAgD8AAACAAACAvwAAAAAAAACAAAAAAAAAgL8AAACAAAAAAAAAAAAAAIC/AACAvwAAAAAAAACAAAAAAAAAAAAAAIA/AAAAAAAAgD8AAACAAACAvwAAAAAAAACAAAAAAAAAgL8AAACAAAAAAAAAAAAAAIA/AgAIAAoAAgAKAAQABwATABcABwAXAAkAEgAMAA8AEgAPABUADQABAAMADQADABEABgAAAA4ABgAOABQAFgAQAAUAFgAFAAsA"
        }
    ]
}

Note the nodes with the attribute “classname”, which is required for idTech engines to function.

However, the .gltf file generated by Create with those same attributes reads like this:

{
  "accessors": [
    {
      "bufferView": 0,
      "componentType": 5125,
      "count": 36,
      "max": [
        29
      ],
      "min": [
        0
      ],
      "name": "Face Vertex Indices Accessor",
      "type": "SCALAR"
    },
    {
      "bufferView": 1,
      "componentType": 5126,
      "count": 30,
      "max": [
        0.5,
        0.5,
        0.5
      ],
      "min": [
        -0.5,
        -0.5,
        -0.5
      ],
      "name": "Face Points Accessor",
      "type": "VEC3"
    },
    {
      "bufferView": 2,
      "componentType": 5126,
      "count": 30,
      "name": "Face Normals Accessor",
      "type": "VEC3"
    },
    {
      "bufferView": 3,
      "componentType": 5126,
      "count": 30,
      "name": "Face UV0 Accessor",
      "type": "VEC2"
    }
  ],
  "animations": null,
  "asset": {
    "generator": "Exported from Omniverse GLTF Converter.",
    "version": "2.0"
  },
  "bufferViews": [
    {
      "buffer": 0,
      "byteLength": 144,
      "target": 34963
    },
    {
      "buffer": 0,
      "byteLength": 360,
      "byteOffset": 144
    },
    {
      "buffer": 0,
      "byteLength": 360,
      "byteOffset": 504
    },
    {
      "buffer": 0,
      "byteLength": 240,
      "byteOffset": 864
    }
  ],
  "buffers": [
    {
      "byteLength": 1104,
      "name": "Model Data",
      "uri": "data:application/octet-stream;base64,AAAAAAEAAAACAAAAAAAAAAMAAAAEAAAABQAAAAYAAAAHAAAABQAAAAgAAAAJAAAACgAAAAsAAAAMAAAACgAAAA0AAAAOAAAADwAAABAAAAARAAAADwAAABIAAAATAAAAFAAAABUAAAAWAAAAFAAAABcAAAAYAAAAGQAAABoAAAAbAAAAGQAAABwAAAAdAAAAAAAAvwAAAL8AAAC/AAAAPwAAAL8AAAC/AAAAPwAAAL8AAAA/AAAAPwAAAL8AAAA/AAAAvwAAAL8AAAA/AAAAvwAAAL8AAAC/AAAAvwAAAD8AAAC/AAAAPwAAAD8AAAC/AAAAPwAAAD8AAAC/AAAAPwAAAL8AAAC/AAAAPwAAAL8AAAC/AAAAPwAAAD8AAAC/AAAAPwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAL8AAAA/AAAAvwAAAL8AAAA/AAAAPwAAAL8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAvwAAAD8AAAA/AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAA/AAAAvwAAAD8AAAA/AAAAvwAAAD8AAAA/AAAAvwAAAD8AAAC/AAAAvwAAAD8AAAC/AAAAvwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAD8AAAC/AAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAACAPwAAgD8AAAAAAACAPwAAAAAAAAAAAAAAAAAAAAAAAIA/AAAAAAAAgD8AAIA/AACAPwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgD8AAIA/AACAPwAAAAAAAIA/AAAAAAAAAAAAAAAAAAAAAAAAgD8AAAAAAACAPwAAgD8AAAAAAACAPwAAAAAAAAAAAAAAAAAAAAAAAIA/AAAAAAAAgD8AAIA/AACAPwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgD8AAIA/AACAPwAAgD8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIA/"
    }
  ],
  "meshes": [
    {
      "name": "worldspawn_cube01",
      "primitives": [
        {
          "attributes": {
            "NORMAL": 2,
            "POSITION": 1,
            "TEXCOORD_0": 3
          },
          "indices": 0,
          "mode": 4
        }
      ]
    }
  ],
  "nodes": [
    {
      "children": [
        1
      ],
      "name": "World",
      "rotation": [
        0.0,
        0.0,
        0.0,
        1.0
      ],
      "scale": [
        1.0,
        1.0,
        1.0
      ],
      "translation": [
        0.0,
        0.0,
        0.0
      ]
    },
    {
      "children": [
        2
      ],
      "name": "worldspawn",
      "rotation": [
        0.0,
        0.0,
        0.0,
        1.0
      ],
      "scale": [
        1.0,
        1.0,
        1.0
      ],
      "translation": [
        0.0,
        0.0,
        0.0
      ]
    },
    {
      "mesh": 0,
      "name": "worldspawn_cube01",
      "rotation": [
        0.0,
        0.0,
        0.0,
        1.0
      ],
      "scale": [
        64.0,
        64.0,
        64.0
      ],
      "translation": [
        0.0,
        3.506000052243471,
        0.0
      ]
    }
  ],
  "scene": 0,
  "scenes": [
    {
      "name": "DefaultScene",
      "nodes": [
        0
      ]
    }
  ]
}

It appears Create enforces a no-dot policy on entity names (worldspawn.cube is force renamed to worldspawn_cube, for example). That can be handled later, but from what I can see the custom attributes were not exported at all for each node.

Do custom attributes need to be added via some other method? Or is that functionality lacking entirely in the current incarnation of Create?

Thanks!