Repository navigation
Materials
Phong and PBR cannot be matched exactly. The conversion policy is intentionally explicit:
| Source | glTF mapping |
|---|---|
Kd |
Linear baseColorFactor; default [0.8, 0.8, 0.8]
|
map_Kd |
sRGB base-color texture, multiplied by Kd; image policy, URI escaped. Options: see below |
Ns |
Approximate perceptual roughness (2 / (Ns + 2))^(1/4)
|
Ks |
KHR_materials_specular, interpreted approximately as normal-incidence reflectance |
Ni |
KHR_materials_ior; default 1.5 |
Pm, Pr
|
Explicit metalness/roughness overrides |
Ke |
Linear emissive factor |
d, Tr
|
Alpha, with d taking precedence regardless of property order; alpha below 1 uses BLEND; a PNG map_Kd also selects BLEND when any of its pixels is less than fully opaque, through an alpha channel or tRNS
|
illum 0 |
KHR_materials_unlit |
illum 1 |
Specular disabled |
illum 4, 9 (glass) |
KHR_materials_transmission of 1 − d; alpha stays 1 and the material OPAQUE
|
illum 6, 7 (refraction) |
KHR_materials_transmission of the mean of Tf (or Kt); d still sets alpha |
Metalness defaults to zero: a large or colored Ks alone does not establish that a surface is metallic. With IOR 1.5, Ks is represented by specularColorFactor = Ks / 0.04; other IOR values use their corresponding Fresnel reflectance. IOR 1 produces zero dielectric reflectance. This preserves the approximate specular color/intensity for extension-aware viewers without inventing metalness. Core-only viewers use the metallic-roughness fallback and will render different specular responses. These material extensions are listed in extensionsUsed, not required, since core-only viewers still render a close fallback.
Material colors and opacity are clamped to [0,1], shininess to nonnegative values, and IOR must be at least 1. Effective Phong parameters are retained under each material's extras.sourcePhong. Scalar colors are treated as linear; exporters that wrote sRGB scalar colors need preprocessing. Ambient Ka is omitted because ambient illumination belongs to the viewer's lighting.
An alpha channel alone does not make a texture transparent: baking and photogrammetry tools often write RGBA PNGs whose alpha is 255 everywhere, and blending them would cost sorting artefacts and a transparent render pass for nothing. PNG textures are therefore decoded row by row on a background thread during the geometry conversion, which limits scan memory to a row and lets the scan overlap geometry processing.
MTL and glTF both separate two kinds of transparency. d dissolves a surface "unlike a real transparent material", which is glTF's alpha as coverage, as in Blender, three.js and obj2gltf. Light passing through a surface, MTL's glass and refraction illumination models, is KHR_materials_transmission, listed in extensionsUsed only; viewers without it render those materials opaque. glTF tints transmitted light with the base color, so Tf's own color is not kept, and Tf under other models is ignored, since some exporters write Tf 1 1 1 on every material. Raw d and Tf values remain in extras.sourcePhong. A used material that ends up fully transparent (d 0, or Tr 1 without d) is kept as written but reported, since it is usually an exporter writing Tr as opacity.
VRML material defaults are preserved, including zero specular color, shininess 0.2, transparency and emissive color. VRML shininess is converted to an exponent using a scale of 128. solid FALSE becomes doubleSided.
map_Kd options from the MTL spec are honoured where glTF can express them:
-
-sand-oscale and offset the texture coordinates. They becomeKHR_texture_transform, listed inextensionsRequiredbecause a viewer without it would place the texture wrongly, sampling ats·uv + oas three.js and Blender do, with the offset converted for glTF's flipped V. Thewcomponent is ignored. -
-clamp onbecomes aCLAMP_TO_EDGEsampler. That is identical within the 0–1 range, but beyond it glTF stretches the edge texels where MTL leaves the bare material; glTF has no closer mode. - Non-default
-mmand-tcannot be represented and are ignored with a warning.-blendu,-blendv,-cc,-texres,-boost,-bmand-imfchando not affect a diffuse map and are skipped. - Any other option is an error, since its argument count, and so where the path starts, is unknown.
Unsupported MTL maps/properties warn explicitly. Missing textures and image formats that cannot be decoded (or require disabled conversion) are errors. Faces without UVs cannot sample a texture, and glTF forbids their primitive from referencing one, so they use a copy of their material without the texture, named <material>-untextured, as obj2gltf does; a warning counts them. Separate opacity/specular/bump maps are not baked into PBR textures. Both OBJ and VRML UVs have V flipped for glTF's texture convention.
Policy references: KHR_materials_specular, VRML lighting model.