class new in Git master
UfbxImporterFBX and OBJ importer using ufbx.
Imports FBX files using ufbx, also supports OBJ files despite the name.
This plugin provides FbxImporter
and ObjImporter
.
Usage
This plugin depends on the Trade and MeshTools libraries and the AnyImageImporter plugin and is built if MAGNUM_WITH_UFBXIMPORTER
is enabled when building Magnum Plugins. To use as a dynamic plugin, load "UfbxImporter"
via Corrade::
Additionally, if you're using Magnum as a CMake subproject, bundle the magnum-plugins repository and do the following:
set(MAGNUM_WITH_UFBXIMPORTER ON CACHE BOOL "" FORCE) add_subdirectory(magnum-plugins EXCLUDE_FROM_ALL) # So the dynamically loaded plugin gets built implicitly add_dependencies(your-app MagnumPlugins::UfbxImporter)
To use as a static plugin or as a dependency of another plugin with CMake, put FindMagnumPlugins.cmake into your modules/
directory, request the UfbxImporter
component of the MagnumPlugins
package and link to the MagnumPlugins::UfbxImporter
target:
find_package(MagnumPlugins REQUIRED UfbxImporter) # ... target_link_libraries(your-app PRIVATE MagnumPlugins::UfbxImporter)
See Downloading and building plugins, Plugin usage with CMake, Loading and using plugins and File format support for more information.
Behavior and limitations
The plugin supports ImporterFeature::
The importer recognizes ImporterFlag::NDEBUG
not defined). The verbose logging prints detailed ufbx
-internal callstacks on load failure that can be used for debugging or reporting issues. ImporterFlag::
Scene import
ufbx
supports only a single scene, though in practice it is extremely rare to have FBX files containing more than a single scene. The only exception is OBJ.mtl
files when opened directly instead of through the top-level.obj
— those are treated as material libraries and thus expose no scene at all.- FBX files may contain nodes with "geometric transforms" that transform only the mesh of the node without affecting children. These are converted to unnamed helper nodes by default, see Geometry transforms for further options and information.
- Imported scenes always have SceneMappingType::
UnsignedInt, with SceneData:: mappingBound() equal to objectCount(). The scene is always 3D. - All reported objects have a SceneField::
Parent (of type SceneFieldType:: Int), SceneField:: Translation (of type SceneFieldType:: Vector3d), SceneField:: Rotation (of type SceneFieldType:: Quaterniond), SceneField:: Scaling (of type SceneFieldType:: Vector3d) and importer-specific flags "visibility"
and"geometricTransformHelper"
(both of type SceneFieldType::Bit). These five fields share the same object mapping with SceneFieldFlag:: ImplicitMapping set. - Scene field
"visibility"
specifies whether objects should be visible in some application-defined manner. - Scene field
"geometryTransformHelper"
is set on synthetic nodes that are not part of the original file, but represent FBX files' ability to transform geometry without affecting children, see Geometry transforms for further details. - If the scene references meshes, a SceneField::
Mesh (of type SceneFieldType:: UnsignedInt) and a SceneField:: MeshMaterial (of type SceneFieldType:: Int) is present, both with SceneFieldFlag:: OrderedMapping set. Missing material IDs are -1
. If a mesh contains multiple materials it is split into parts and the node contains each part as a separate mesh/material entry. The same mesh can appear instanced multiple times under many nodes with different materials. - If the scene references cameras, a SceneField::
Camera (of type SceneFieldType:: UnsignedInt) is present, with SceneFieldFlag:: OrderedMapping set. A single camera can be referenced by multiple nodes. - If the scene references lights, a SceneField::
Light (of type SceneFieldType:: UnsignedInt) is present, with SceneFieldFlag:: OrderedMapping set. A single light can be referenced by multiple nodes. - The node transformations are expressed in a file dependent units and axes. UfbxImporter supports normalizing them to a consistent space, see Unit normalization for further details.
Material import
- Supports both legacy FBX Phong material model and more modern PBR materials, in some cases both are defined as PBR materials may have a legacy Phong material filled as a fallback.
- PBR material properties in OBJ files are supported as well.
- The legacy FBX material model and most PBR material models have factors for various attributes, by default these are premultiplied into the value but you can retain them using the
preserveMaterialFactors
configuration option ufbx
tries to normalize the various vendor-specific PBR material modes into a single set of attributes that are imported, see PBR material attributes for an exhaustive listing.- MaterialAttribute::
DiffuseTextureMatrix and similar matrix attributes for other textures are imported. - MaterialAttribute::
DiffuseTextureCoordinates and similar UV layer attributes are not supported, as FBX stores them as UV set names instead of layer indices, and the conversion would be fragile. - FBX materials have no equivalent for the MaterialAttribute::
DoubleSided, MaterialAttribute:: AlphaMask and MaterialAttribute:: AlphaBlend properties, and thus they are undefined for materials. - In addition to opening OBJ files,
ufbx
allows directly opening a.mtl
file, which will result in just the material data being parsed, without any meshes or a scene present.
Light import
- LightType::
Directional and LightType:: Ambient expect the attenuation to be constant, but FBX is not required to follow that. In that case the attenuation value from the file is ignored. - Area and volume lights are not supported
Mesh import
- Vertex creases and any edge or face attributes are not imported
- The importer follows types used by
ufbx
truncated to 32-bit, thus indices are always MeshIndexType::UnsignedInt, positions, normals, tangents and bitangents are always imported as VertexFormat:: Vector3, texture coordinates as VertexFormat:: Vector2 and colors as VertexFormat:: Vector4. Most FBX files contain geometry data natively as double-precision floats. - If a mesh contains multiple materials it is split into parts and the node contains each part as a separate mesh/material entry.
- If a mesh contains faces with 1 or 2 vertices (ie. points or lines) they are separated to meshes with the correct primitives (MeshPrimitive::
Points and Lines) - Faces with more than three vertices are triangulated and represented as MeshPrimitive::
Triangles.
The meshes are indexed by default unless generateIndices
configuration option is disabled. Vertex position is always defined, normals can be missing unless generateMissingNormals
configuration option is set. There are an arbitrary amount of UV/tangent/bitangent/color sets, you can specify a maximum limit using maxUvSets
, maxTangentSets
and maxColorSets
configuration options, note that setting any to zero disables loading any tangents etc.
Animation and skin import
- FBX represents rotations using Euler angles, which are converted to quaternions on import.
- Cubic FBX animation curves are resampled to linear interpolation as time tangents prevent representing them via cubic Hermite splines. The resampling rate can be configured via the
resampleRate
configuration option. - As FBX represents rotations using Euler angles, even linear rotations are resampled by default to preserve the original motion. This can be disabled via the
resampleRotation
configuration option. - FBX supports animating object visibility as well, which are imported with a custom animation track target named
"visibility"
- Morph targets are not supported
- Animation tracks are always imported with Animation::
Extrapolation:: Constant because FBX does not contain any extrapolation information. - UfbxImporter imports FBX animation stacks as individual animations by default. You can specify the
animationLayers
configuration option to import each animation layer as an individual animation. Currently this loses information about what layers animation stacks contain. - As many FBX exporters resample animations already, to avoid double resampling UfbxImporter will avoid resampling closely spaced keyframes. This interval can be adjusted via the
minimumSampleRate
configuration option. - Constant keyframes are represented as nearly-equal time keyframes. The constant interpolation interval can be adjusted via the
constantInterpolationDuration
configuration option. - Skin deformers are supported but only the first skin deformer for a mesh is imported at the moment.
Texture import
- Only textures with filenames are retained in the imported scene as textures.
- Layered textures are converted into material layers.
- FBX textures have no defined SamplerFilter, so UfbxImporter sets all filters to SamplerFilter::
Linear.
Image import
- Both external and embedded images are supported via the AnyImageImporter plugin.
- Only 2D images are supported.
Scene processing
Plain FBX files can be tedious to work with as they can contain unusual scene graph features and may be defined in arbitrary coordinate/unit spaces. ufbx
can process the scene representation internally to make it easier to interpret, which is exposed as configuration options explained below.
Unit normalization
FBX supports arbitrary coordinate systems and units. The default unit is in centimeters (which can often be seen as exporting a file from Blender with the default settings and ending up with a file where everything is 100x larger), though meters and even inches are reasonably common. The coordinate systems most commonly are right-handed Y-up or Z-up.
Currently the plugin does not support querying the coordinate/unit system of the file so the only way to deal with units is using the normalizeUnits
configuration option. This will normalize the file into the glTF system: units are one meter and the coordinates are +X right, +Y up, -Z forward (+Z front in FBX terms). By default the option will adjust the object transforms directly, meaning if you load a file authored in the glTF space it should look like what it did before exporting.
If you want to retain the node transformations written in the FBX file, you can set unitNormalizationHandling=transformRoot
in the configuration, this will result in the scene containing an additional root node containing the unit/axis transform as transform/rotation/scaling.
Geometry transforms
FBX nodes can contain somewhat confusingly named "geometric transforms" which are referred to "geometry transforms" here for clarity. These transformations only affect the immediate geometry (or rarely attached light, camera, etc.) of the node, without transforming the child nodes. Most scene graphs don't natively support this, including the standard one in SceneData.
By default UfbxImporter creates "helper nodes" that contain the geometry transforms, so by default they will be transparently supported without any extra implementation effort. SceneData returned by UfbxImporter contains an extra SceneField named "geometryTransformHelper"
mapped implicitly per node containing information whether a node is a helper or a normal one.
You can change how UfbxImporter handles the geometry transforms via the geometryTransformHandling
configuration option, the default option being helperNodes
.
Using modifyGeometry
will attempt to elide the helper nodes by modifying the actual mesh geometry, "baking" the geometry transform into the vertex data. This will fall back into creating helper nodes if necessary, for example for lights/cameras or instanced meshes.
Using preserve
will not modify the scene at all and exposes the original geometry transform values via three additional SceneFields per node: "geometryTranslation"
(SceneFieldType::"geometryRotation"
(SceneFieldType::"geometryRotation"
(SceneFieldType::
PBR material attributes
ufbx
normalizes PBR materials into a superset of all vendor-specific PBR material models that ufbx
supports, these attributes are exposed as custom MaterialAttribute names.
Majority of the attributes match Autodesk Standard Surface parameters:
Layer | Attribute | Type | OSL parameter |
---|---|---|---|
(base) | baseColorFactor 1 | Float | base |
(base) | BaseColor | Vector4 | base_color |
(base) | Roughness | Float | specular_roughness |
(base) | Metalness | Float | metalness |
(base) | diffuseRoughness | Float | diffuse_roughness |
(base) | specularColorFactor 1 | Float | specular |
(base) | SpecularColor | Vector4 | specular_color |
(base) | specularIor | Float | specular_IOR |
(base) | specularAnisotropy | Float | specular_anisotropy |
(base) | specularRotation | Float | specular_rotation |
(base) | thinFilmThickness | Float | thin_film_thickness |
(base) | thinFilmIor | Float | thin_film_IOR |
(base) | emissiveColorFactor 1 | Float | emission |
(base) | EmissiveColor | Vector3 | emission_color |
(base) | opacity | Vector3 | opacity |
ClearCoat | LayerFactor | Float | coat |
ClearCoat | color | Vector4 | coat_color |
ClearCoat | Roughness | Float | coat_roughness |
ClearCoat | ior | Float | coat_IOR |
ClearCoat | anisotropy | Float | coat_anisotropy |
ClearCoat | rotation | Float | coat_rotation |
ClearCoat | NormalTexture | UnsignedInt | coat_normal |
transmission | LayerFactor | Float | transmission |
transmission | color | Vector4 | transmission_color |
transmission | depth | Float | transmission_depth |
transmission | scatter | Vector3 | transmission_scatter |
transmission | scatterAnisotropy | Float | transmission_scatter_anisotropy |
transmission | dispersion | Float | transmission_dispersion |
transmission | extraRoughness | Float | transmission_extra_roughness |
subsurface | LayerFactor | Float | subsurface |
subsurface | color | Vector4 | subsurface_color |
subsurface | radius | Vector3 | subsurface_radius |
subsurface | scale | Float | subsurface_scale |
subsurface | anisotropy | Float | subsurface_anisotropy |
sheen | LayerFactor | Float | sheen |
sheen | color | Vector3 | sheen_color |
sheen | Roughness | Float | sheen_roughness |
- 1.
- Requires
preserveMaterialFactors
configuration option to be enabled.
Other attributes not defined by the OSL Standard Surface:
Layer | Attribute | Type | Description |
---|---|---|---|
(base) | Glossiness | Float | Inverse of roughness used by some material models |
(base) | NormalTexture | UnsignedInt | Tangent-space normal map texture |
(base) | OcclusionTexture | UnsignedInt | Ambient occlusion texture |
(base) | tangentTexture | UnsignedInt | Tangent re-orientation texture |
(base) | displacementTexture | UnsignedInt | Displacement texture |
(base) | displacementFactor | Float | Displacement texture weight |
(base) | indirectDiffuse | Float | Factor for indirect diffuse lighting |
(base) | indirectSpecular | Float | Factor for indirect specular lighting |
ClearCoat | Glossiness | Float | Inverse of roughness used by some material models |
ClearCoat | affectBaseColor | Float | Modify the base color based on the coat color |
ClearCoat | affectBaseRoughness | Float | Modify the base roughness based on the coat roughness |
transmission | Roughness | Float | Transmission roughness (base Roughness not added) |
transmission | Glossiness | Float | Inverse of roughness used by some material models |
transmission | priority | Long | IOR transmission priority |
transmission | enableInAov | Bool | Render transmission into AOVs (Arbitrary Output Variable) |
subsurface | tintColor | Vector4 | Extra tint color that is multiplied after SSS calculation |
subsurface | type | Long | Shader-specific subsurface random walk type |
matte | LayerFactor | Float | Matte surface weight |
matte | color | Vector3 | Matte surface color |
Plugin-specific configuration
It's possible to tune various import options through configuration(). See below for all options and their default values:
[configuration] # Generate normals if missing. generateMissingNormals=false # Fail if the file is slightly malformed. strict=false # Disable any exporter-specific quirks in the importer. disableQuirks=false # Attempt to load further files referenced by this file. # On .obj files this would include .mtl files. loadExternalFiles=true # Ignore all geometry (vertices, indices) during loading. ignoreGeometry=false # Ignore all animation data (curves) during loading. ignoreAnimation=false # Ignore embedded data (such as images) during loading. ignoreEmbedded=false # Ignore all the actual content in the file, only loading the scene # information such as object relationships and names. ignoreAllContent=false # Maximum amount of temporary memory in bytes to use, negative for unlimited. # Loading is aborted if memory usage exceeds this limit. maxTemporaryMemory=-1 # Maximum amount of result memory in bytes to use, negative for unlimited. # Loading is aborted if memory usage exceeds this limit. maxResultMemory=-1 # Normalize units to meters with right-handed Y up coordinates. # This coordinate/unit system matches the glTF specification. normalizeUnits=false # Method of handling FBX "geometric transforms" that offset geometry from # nodes without affecting children in the hierarchy. Possible values: # - helperNodes -- add dummy nodes between nodes and meshes where needed # - modifyGeometry -- modify the geometry data if possible, fall back to # helperNodes in some edge cases. # - preserve -- retain the geometry transforms as additional custom # SceneFields -- GeometryTranslation as Vector3d, GeometryRotation as # Quaterniond and GeometryScaling as Vector3d geometryTransformHandling=helperNodes # Method of handling normalizeUnits. Note that if set to transformRoot the # root node is retained even if normalizeUnits=false. Possible values: # - adjustTransforms -- modify the top-level node transforms # - transformRoot -- retain an additional root node where the # coordinate/unit transform is stored as a normal TRS tuple unitNormalizationHandling=adjustTransforms # Deduplicate raw vertex data to an indexed mesh. generateIndices=true # Maximum number of UV sets per vertex, use negative for unbounded. maxUvSets=-1 # Maximum number of tangent/bitangent sets per vertex, use negative for # unbounded. maxTangentSets=-1 # Maximum number of vertex color sets per vertex, use negative for unbounded. maxColorSets=-1 # Maximum number of joint weights per vertex, use negative for unbounded. maxJointWeights=-1 # Preserve factor attributes for materials instead of premultiplying them. # For example instead of a single BaseColor the importer would return both # BaseColor and baseColorFactor. preserveMaterialFactors=false # Import individual animation layers instead of animation stacks. animationLayers=false # Sampling rate in Hz (frames per second) for non-linear animation curves. resampleRate=30 # Resample rotation to preserve Euler interpolation in the file. resampleRotation=true # Minimum sampling rate for animation that will not be resampled. minimumSampleRate=20 # Time interval in seconds for non-continuous steps in the animation. constantInterpolationDuration=0.001 # Include all TRS components always if even one is defined animateFullTransform=false
See Editing plugin-specific configuration for more information and an example showing how to edit the configuration values.
Base classes
- class AbstractImporter
- Base for importer plugins.
Constructors, destructors, conversion operators
-
UfbxImporter(PluginManager::
AbstractManager& manager, const Containers:: StringView& plugin) explicit - Plugin manager constructor.