Suppose someone selects a .zip
file (<input type="file">
) with the following content:
3d-model.zip
|- 3d-model.obj
|- 3d-model.mtl
|- texture1.jpg
|- texture2.jpg
Here are some methods I tried
✔️ means that it worked
✖️ means that it didn't work
✔️ #1 Mesh-only
const objBlob = await createBlob(zipfiles['3d-model.obj'])
const objUrl = URL.createObjectURL(objBlob)
const objLoader = new THREE.OBJLoader()
objLoader.load(objUrl, obj => {
// mesh is displayed correctly
scence.add(obj)
const gltfExporter = new GLTFExporter()
// parsing works fine
gltfExporter.parse(obj, result => {
const output = JSON.stringify(result, null, 2)
const blob = new Blob([output], { type: 'text/plain' }, `3d-model.gltf`)
})
})
✔️ #2 Mesh with simple material
# 3d-model.mtl file
newmtl material1
Kd 0 1 0
newmtl material2
Kd 1 0 0
const objBlob = await createBlob(zipfiles['3d-model.obj'])
const objUrl = URL.createObjectURL(objBlob)
const mtlBlob = await createBlob(zipfiles['3d-model.mtl'])
const mtlUrl = URL.createObjectURL(mtlBlob)
const mtlLoaer = new THREE.MTLLoader()
mtlLoader.load(mtlUrl, mtl => {
const objLoader = new THREE.OBJLoader()
objLoader.setMaterials(mtl)
objLoader.load(objUrl, obj => {
// mesh is displayed correctly
scence.add(obj)
// parsing works fine
const gltfExporter = new GLTFExporter()
gltfExporter.parse(obj, result => {
const output = JSON.stringify(result, null, 2)
const blob = new Blob([output], { type: 'text/plain' }, `3d-model.gltf`)
})
})
})
✖️ #3 Mesh + material with texture maps
# 3d-model.mtl file
newmtl material1
map_Kd texture1.jpg
newmtl material2
map_Kd texture2.jpg
const objBlob = await createBlob(zipfiles['3d-model.obj'])
const objUrl = URL.createObjectURL(objBlob)
const mtlBlob = await createBlob(zipfiles['3d-model.mtl'])
const mtlUrl = URL.createObjectURL(mtlBlob)
const mtlLoaer = new THREE.MTLLoader()
mtlLoader.load(mtlUrl, mtl => {
const objLoader = new THREE.OBJLoader()
objLoader.setMaterials(mtl)
objLoader.load(objUrl, obj => {
// error while adding mesh (see screenshot below)
scence.add(obj)
// parsing throws error (see screenshot below)
const gltfExporter = new GLTFExporter()
gltfExporter.parse(obj, result => {
const output = JSON.stringify(result, null, 2)
const blob = new Blob([output], { type: 'text/plain' }, `3d-model.gltf`)
})
})
})
I get some errors, which makes total sense (because those textures do not exist at this location)
Error while adding mesh to the scene
Error while parsing to GLTF
https://github.com/mrdoob/three.js/blob/398c4f39ebdb8b23eefd4a7a5ec49ec0c96c7462/examples/jsm/exporters/GLTFExporter.js#L778
✖️ #4 So, I tried the following
# 3d-model.mtl file
newmtl material1
map_Kd texture1.jpg
newmtl material2
map_Kd texture2.jpg
const objBlob = await createBlob(zipfiles['3d-model.obj'])
const objUrl = URL.createObjectURL(objBlob)
const texture1Blob = await createBlob(zipfiles['texture1.jpg'])
const texture1Url = URL.createObjectURL(texture1Blob)
const texture2Blob = await createBlob(zipfiles['texture2.jpg'])
const texture2Url = URL.createObjectURL(texture2Blob)
const mtlFileContent = `
newmtl material1
map_Kd ${texture1Url}
newmtl material2
map_Kd ${texture2Url}
`
const mtlBlob = new Blob([mtlFileContent])
const mtlUrl = URL.createObjectURL(mtlBlob)
const mtlLoaer = new THREE.MTLLoader()
mtlLoader.load(mtlUrl, mtl => {
const objLoader = new THREE.OBJLoader()
objLoader.setMaterials(mtl)
objLoader.load(objUrl, obj => {
// adding the object to the scence works fine (with materials and textures)
scence.add(obj)
// but parsing throws error (see screenshot below)
const gltfExporter = new GLTFExporter()
gltfExporter.parse(obj, result => {
const output = JSON.stringify(result, null, 2)
const blob = new Blob([output], { type: 'text/plain' }, `3d-model.gltf`)
})
})
})
With this method, the object is added to the Three.js scene with materials and textures. Awesome! But the GLTFExporter
still isn't happy:
Error while parsing to GLTF
https://github.com/mrdoob/three.js/blob/398c4f39ebdb8b23eefd4a7a5ec49ec0c96c7462/examples/jsm/exporters/GLTFExporter.js#L778
It seems like the GLTFExporter
cant fetch blob URLs?!
Do I need to rewrite the GLTFExporter
to support "blob URLs" or is there another way to load the textures from a zip file?