class new in Git master
GltfSceneConverterglTF converter plugin
Exports full scenes to either *.gltf
files with an external *.bin
buffer or to a self-contained *.glb
. You can use GltfImporter to import scenes in this format.
Usage
This plugin depends on the Trade library and is built if WITH_GLTFSCENECONVERTER
is enabled when building Magnum Plugins. To use as a dynamic plugin, load "GltfSceneConverter"
via Corrade::
Additionally, if you're using Magnum as a CMake subproject, bundle the magnum-plugins repository and do the following:
set(WITH_GLTFSCENECONVERTER ON CACHE BOOL "" FORCE) add_subdirectory(magnum-plugins EXCLUDE_FROM_ALL) # So the dynamically loaded plugin gets built implicitly add_dependencies(your-app MagnumPlugins::GltfSceneConverter)
To use as a static plugin or as a dependency of another plugin with CMake, put FindMagnumPlugins.cmake into your modules/
directory, request the GltfSceneConverter
component of the MagnumPlugins
package and link to the MagnumPlugins::GltfSceneConverter
target:
find_package(MagnumPlugins REQUIRED GltfSceneConverter) # ... target_link_libraries(your-app PRIVATE MagnumPlugins::GltfSceneConverter)
See Downloading and building plugins, Plugin usage with CMake, Loading and using plugins and File format support for more information.
Behavior and limitations
- At the moment, alignment rules for the
*.glb
layout are not respected.
Mesh export
- The MeshData is exported with its exact binary layout. Only padding before and after an index view is omitted, the vertex buffer is saved verbatim into the glTF buffer.
- MeshPrimitive::
Points, Lines, LineLoop, LineStrip, Triangles, TriangleStrip and TriangleFan is supported by core glTF. Implementation-specific primitive types can't be exported. - Both non-indexed and indexed meshes with MeshIndexType::
UnsignedShort or MeshIndexType:: UnsignedInt are supported by core glTF, MeshIndexType:: UnsignedByte is supported but discouraged. Implementation-specific index types and non-contiguous index arrays can't be exported. - While glTF has a requirement that vertex / index count corresponds to the actual primitive type, the exporter doesn't check that at the moment. Attribute-less meshes and meshes with zero vertices are not allowed by the spec but GltfImporter supports them and they can be exported with a warning if you disable the
strict
configuration option. Attribute-less meshes with a non-zero vertex count are unrepresentable in glTF and thus can't be exported. - MeshAttribute::
Position in VertexFormat:: Vector3 is supported by core glTF; Vector3b, Vector3bNormalized, Vector3ub, Vector3ubNormalized, Vector3s, Vector3sNormalized, Vector3us or Vector3usNormalized will be exported with KHR_ mesh_ quantization being added to required extensions. Other formats or 2D positions are not supported. At the moment, the position attribute doesn't have the min
andmax
properties calculated even though required by the spec. - MeshAttribute::
Normal in VertexFormat:: Vector3 is supported by core glTF; Vector3bNormalized and Vector3sNormalized will be exported with KHR_ mesh_ quantization being added to required extensions. No other formats are supported. - MeshAttribute::
Tangent in VertexFormat:: Vector4 is supported by core glTF; Vector4bNormalized and Vector4sNormalized will be exported with KHR_ mesh_ quantization being added to required extensions. No other formats are supported. Three-component tangents and separate bitangents will be exported as a custom _TANGENT3
/_BITANGENT
attributes under rules that apply to custom attributes as described below. - MeshAttribute::
TextureCoordinates in VertexFormat:: Vector2, Vector2ubNormalized and Vector2usNormalized are supported by core glTF. The data are by default Y-flipped unless the textureCoordinateYFlipInMaterial
configuration option is enabled. Vector2b, Vector2bNormalized, Vector2ub, Vector2s, Vector2sNormalized or Vector2us will be exported with KHR_mesh_ quantization being added to required extensions. Those can't be Y-flipped and thus require the textureCoordinateYFlipInMaterial
option to be explicitly enabled. Other formats are not supported. - MeshAttribute::
Color in VertexFormat:: Vector3 / Vector4, Vector3ubNormalized / Vector4ubNormalized and Vector3usNormalized / Vector4usNormalized are supported by core glTF. No other formats are supported. MeshAttribute:: ObjectId in VertexFormat:: UnsignedByte and VertexFormat:: UnsignedShort is exported as _OBJECT_ID
by default, use theobjectIdAttribute
configuration option to change the identifier name. glTF allows 32-bit integers only for index types, exporting VertexFormat::UnsignedInt is possible with a warning if you disable the strict
configuration option. - Custom attributes are exported with identifiers set via setMeshAttributeName(), and unless the custom attribute corresponds to a builtin glTF attribute, the name should be prefixed with a
_
to adhere to the spec. If no name was set for an attribute, it's exported with an underscore followed by its numeric value extracted using meshAttributeCustom(MeshAttribute). Allowed formats are VertexFormat::Float, Byte, ByteNormalized, UnsignedByte, UnsignedByteNormalized, Short, ShortNormalized, UnsignedShort, UnsignedShortNormalized, its 2-, 3- and 4-component vector counterparts, Matrix2x2, Matrix2x2bNormalizedAligned, Matrix2x2sNormalized, Matrix3x3, Matrix3x3bNormalizedAligned, Matrix3x3sNormalizedAligned, Matrix4x4, Matrix4x4bNormalized and Matrix4x4sNormalized. Exporting VertexFormat,UnsignedInt, Vector2ui, Vector3ui and Vector4ui is possible with a warning if you disable the strict
configuration option. Signed 32-bit integers, half-floats, doubles or packed types are not representable in glTF, implementation-specific vertex formats can't be exported. - MeshAttribute::
TextureCoordinates, MeshAttribute:: Color, (custom) JOINTS
andWEIGHTS
attributes are suffixed with_0
,_1
, ... for each occurence. Second and following occurences of other attributes are prefixed with an underscore if not already and suffixed with_1
,_2
, ..., so e.g. a second position attribute becomes_POSITION_1
. - Mesh name, if passed, is saved into the file. Additionally the buffer views and accessors referenced by it will be annotated with mesh ID and name, and attribute index and name if the
accessorNames
configuration option is enabled. - Due to a material and a mesh being tied together in a glTF file, meshes that are referenced by a scene are written in the order they are referenced from SceneData, and get duplicated (including the name) if the same mesh gets used with different materials.
- At the moment, alignment rules for vertex stride are not respected.
- At the moment, each attribute has its own dedicated buffer view instead of a single view being shared by multiple interleaved attributes. This also implies that for single-vertex meshes the buffer view size might sometimes be larger than stride, which is not allowed by the spec.
Image and texture export
- Images are converted using a converter specified in the
imageConverter
configuration option, propagating flags set via setFlags() and all configuration options from the[imageConverter]
group to it. An AbstractImageConverter plugin manager has to be registered using PluginManager::Manager:: registerExternalManager() for image conversion to work. - By default, images are saved as external files for a
*.gltf
output and embedded into the buffer for a*.glb
output. This behavior can be overriden using thebundleImages
configuration option on a per-image basis. - Core glTF supports only JPEG and PNG file formats. Basis-encoded KTX2 files can be saved with the KHR_
texture_ basisu extension by setting imageConverter=BasisKtxImageConverter
. The MSFT_texture_ dds and EXT_ texture_ webp extensions are not exported because there's currently no image converter capable of saving DDS and WebP files. Other formats (such as TGA, OpenEXR...) are not supported by the spec but GltfImporter supports them and they can be exported if the strict
configuration option is disabled. Such images are then referenced directly without any extension. - If the
experimentalKhrTextureKtx
configuration option is enabled, generic KTX2 images can be saved with the proposed KHR_texture_ ktx extension. - Image and texture names, if passed, are saved into the file. Additionally the buffer views referenced by embedded images will be annotated with image ID and name if the
accessorNames
configuration option is enabled. - The texture is required to only be added after all images it references
- At the moment, there's no support for exporting multi-level images even though the KTX2 container is capable of storing these.
2D array texture export
If the experimentalKhrTextureKtx
configuration option is enabled, the plugin supports also 3D images and 2D array textures using a proposed KHR_
- Only KTX2 images are supported for 3D, i.e. with either
imageConverter=KtxImageConverter
orimageConverter=BasisKtxImageConverter
. They need to have ImageFlag3D::Array set. - Use a TextureType::
Texture2DArray texture to reference the 3D images. Due to how the extension is designed, the resulting glTF then has the texture duplicated for each layer of the image; GltfImporter then undoes the duplication again on import. - Due to how the extension is designed, the presence of the texture referencing the 3D image is essential for properly recognizing the image as 3D on import. Without it, the image gets recognized as 2D and the import will subsequently fail due to the image file not actually being 2D.
- A material referencing a 2D array texture implicitly uses the first (
0
) layer. Use the*TextureLayer
attributes (such as MaterialAttribute::BaseColorTextureLayer for a MaterialAttribute:: BaseColorTexture) to specify a layer. The layer index has to be smaller than the Z dimension of the image.
Material export
- Implicitly, only attributes that from glTF material defaults are written to save file on size. Enable the
keepMaterialDefaults
configuration option to write them as well. - Both a separate MaterialAttribute::
MetalnessTexture and MaterialAttribute:: RoughnessTexture as well as a combined MaterialAttribute:: NoneRoughnessMetallicTexture is supported, but either both or neither textures have to be present and have to satisfy glTF packing rules as described in PbrMetallicRoughnessMaterialData:: hasNoneRoughnessMetallicTexture(). - MaterialAttribute::
NormalTextureSwizzle has to be MaterialTextureSwizzle:: RGB, if present; MaterialAttribute:: OcclusionTextureSwizzle has to be MaterialTextureSwizzle:: R, if present. - If MaterialType::
Flat is present, the KHR_ materials_ unlit extension is included in the output. Other MaterialTypes are ignored, the material is only filled based on the attributes present. - If any MaterialAttribute::
*TextureMatrix attributes are present, the KHR_ texture_ transform extension is included in the output. At the moment, only offset and scaling is written, rotation is ignored with a warning. If the textureCoordinateYFlipInMaterial
configuration option is enabled, all material textures will contain an Y-flip transformation in addition to any existing transformation. - Material names, if passed, are saved into the file
- The material is required to only be added after all textures it references
- An informational warning is printed for all attributes that were unused due to not having a glTF equivalent, due to referring to a texture but the texture attribute isn't present or due to the support not being implemented yet. The only exception is Phong MaterialAttribute::
DiffuseColor and DiffuseTexture properties if they match the corresponding MaterialAttribute:: BaseColor / BaseColorTexture attributes. Such attributes are produced by GltfImporter for compatibility purposes when the phongMaterialFallback
configuration option is enabled and are redundant. - At the moment, custom material properties and layers are not exported
Scene export
- Only 3D scenes are supported
- Only objects with a SceneField::
Parent entry are exported, all other objects are ignored with a warning. This also implies that object IDs are not preserved, as otherwise the glTF would contain a lot of empty unreferenced node objects. - The SceneField::
Parent hierarchy is required to be acyclical - To satisfy glTF requirements, if both SceneField::
Transformation and at least one of Translation, Rotation and Scaling is present, only the TRS component(s) are saved into the file and not the matrix, assuming the transformation matrix is equivalent to them - Object and scene names, if passed, are saved into the file
- The scene is required to only be added after all meshes and materials it references
- Custom SceneFieldType::
Float, SceneFieldType:: UnsignedInt and SceneFieldType:: Int fields are exported if a name is set for them via setSceneFieldName(). Custom fields of other types and without a name assigned are ignored with a warning. - At the moment, only SceneField::
Parent, Transformation, Translation, Rotation, Scaling, Mesh and MeshMaterial is exported, other builtin fields are ignored with a warning - At the moment, duplicate fields including multiple mesh assignments are ignored with a warning
- At the moment, only a single scene can be exported. As a consequence, information about the default scene is redundant and thus not written.
Plugin-specific config
It's possible to tune various output options through configuration(). See below for all options and their default values:
[configuration] # Copyright and generator name, written into the asset object. If empty, no # value is written. copyright= generator=Magnum GltfSceneConverter # Add one or more extensionUsed and/or extensionRequired values to populate # the extension usage and requirement arrays. # Whether to write a *.gltf or a *.glb file. If empty, detected automatically # based on filename extension, conversion to data defaults to a binary file. # If a text file is selected for conversion to data, converting anything that # involves binary buffers will currently fail. binary= # Name all buffer views and accessors to see what they belong to. Useful for # debugging purposes. The option can be also enabled just for a particular # add() operation and then disabled again to reduce the impact on file sizes. accessorNames=false # Allow only strictly valid glTF files. Disallows: # - Meshes with zero vertices, zero indices or zero attributes # - Meshes with 32-bit integer attributes # - Image formats that don't have a corresponding glTF extension # Magnum's GltfImporter will be able to open files with this option unset # (unless it's own strict option is enabled), but other libraries may fail. # The option can be also disabled just for a particular add() operation and # then enabled again to not loosen up validation for everything at once. strict=true # Perform Y-flip for texture coordinates in a material texture transform. By # default texture coordinates are Y-flipped directly in the mesh data to # avoid the need to supply texture transformation matrix to a shader, # enabling this will cause all texture coordinate data to be unchanged and # instead all materials will have a Y-flipping texture transformation # present. Note that this flag has to be enabled before beginning a file, # changing it during conversion will have undefined behavior. textureCoordinateYFlipInMaterial=false # The non-standard MeshAttribute::ObjectId is by default recognized under # this name. Change if you want to export it under a different identifier. objectIdAttribute=_OBJECT_ID # Implicitly, only material attributes that differ from glTF material # defaults are written. Enable to unconditionally save all attributes present # in given MaterialData. Attributes that are not present in given # MaterialData are saved only if the Magnum default differs from the glTF # default and this option doesn't affect them. keepMaterialDefaults=false # Whether to bundle images in buffers. If empty, images are bundled for *.glb # files and saved externally for *.gltf files. Can be set differently for # each add() operation. bundleImages= # Experimental KHR_texture_ktx support. The extension is not stabilized yet, # thus the implementation may not reflect latest changes to the proposal. experimentalKhrTextureKtx=false # Image converter to use. Can be set differently for each add() operation in # order to export different images in different formats. Formats that don't # have any corresponding glTF image extension are allowed only with the # strict option unset. imageConverter=PngImageConverter # Configuration options to propagate to the image converter [configuration/imageConverter]
See Editing plugin-specific configuration for more information and an example showing how to edit the configuration values.
Base classes
- class AbstractSceneConverter new in 2020.06
- Base for scene converter plugins.
Constructors, destructors, conversion operators
-
GltfSceneConverter(PluginManager::
AbstractManager& manager, const Containers:: StringView& plugin) explicit - Plugin manager constructor.