Maciej Główka
Blog Games Contact

← Return to Blog Index

mtl.JPG
Jan. 2, 2022

OBJ with MTL and textures from THREE.js

webdev javascript

Recently we have added the ability to download 3d models from our furniture website pikle.eu. Internally we store models in GLTF format - for webpage and AR use (via model-viewer.dev). Since it is not the most popular file format among interior designers, we have decided to provide client-side on-the-fly conversion.

Luckily THREE.js had two working exporters for us right away - COLLADA and OBJ. Only the latter one did not export materials nor texture files...

The OBJs do not store material data inside same geometry file - a separate *.mtl one is created, which had actually simplified the process for us :) We just had to build the material description file (which is pure text), and add literally a single of data to the original *.obj.

As our models are rather simple we did not implement any fancy stuff, such as normal maps, emission or transparency - but feel free to build upon our code :) You can check the meaning of all MTL parameters eg. here: https://people.sc.fsu.edu/~jburkardt/data/mtl/mtl.html

The procedure here is pretty straightforward. We traverse all the objects in the scene and check for materials. Every new material we find is passed to a helper function that builds necessary text data, which is then appended to a temp variable. Each line describes a single shader property: Kd is for diffuse RGB, Ns is specular and so on.

The variable is finally written to a text file with the *.mtl extension. ('model.mtl' in our case). We need to also add a 'mtllib model.mtl' line at the beginning of the original *.obj file, as otherwise some 3d apps might not make this association by themselves.

If a texture map is found (only diffuse / albedo) we also specify that in the material description and extract a *.png file from the scene.

For sake of simplicity all the resources found are simply appended as downloadable links to the HTML document. We also do not use any proper THREE.js scene here - we take it from an existing GLTF file - but that does not change much in the material extraction procedure :)

← Batch GLTF material variants in Blender Making Axum server to listen over a Unix socket→