I have seen plenty of examples on how to export a mesh or a whole scene from ThreeJS to an OBJ file. Starting from MrDoob example here:https://threejs.org/examples/#misc_exporter_obj
But since a marching cube like this : https://threejs.org/examples/webgl_marchingcubes.html is not an instance of THREE.Mesh, what would be the workaround to export its current geometry into an Obj file? And by extension its material into an mtl file as explained in this question : Export a three js textured model to a .OBJ with .MTL file
EDIT
As far as I understand, it is possible to export a copy of the current state of the metaballs by using the generateGeometry() function provided by marching cubes. Below is an example using filesaver.js and JSZip.js to export the geometry and material as two files in a zip. THREE.OBJExporter comes from the modified version of the original obj exporter of threeJS done as mentionned above (Export a three js textured model to a .OBJ with .MTL file):
function exportToObj(the_object){
var zip = new JSZip();
var the_exporter = new THREE.OBJExporter();
var result = the_exporter.parse(the_object);
zip.file("Blob.obj", result.obj);
zip.file("Blob.mtl", result.mtl);
zip.generateAsync({type:"blob"}).then(function (blob) {
saveAs(blob, "Blob.zip");
});
}
$(document).on('keyup',function(e) {
if (e.which == 13){ // enter key to export to OBJ
var TempMesh = new THREE.Mesh(effect.generateGeometry(),effect.material);
//effect is of the type: new THREE.MarchingCubes()
exportToObj(TempMesh);
}
});
In that way, if a color is provided to the material, it will be exported in the .mtl file. But the last missing piece is probably how to properly convert a shaderMaterial for example? Save it as a texture maybe?
Related
I exported an object from Blender to a gltf-file and imported it into my three.js project. (Including materials, ive got 2 in total)
let loader = new THREE.GLTFLoader();
loader.load('Objects/MyBox.gltf', (gltf) => {
let box = gltf.scene;
box.traverse((child) => {
if (child.isMesh) child.material = boxMaterial; // a material i created in the code earlier
});
scene.add(box);
});
This code causes my imported Object (which is a folded box) to have the same material (boxMaterial) on the outside and on the inside.
But as i created it in bleder ( inside of the box has an inside material, the outside has an outside material) i want it to be in my three.js project. What I want is = the boxMaterial(created in three.js) shall only be on the outside-Material(created in blender).
My question is -> how do I tell/access the specific imported material of my imported object to have a certain material in three.js?
In easier words: My "child.material" contains my needed materials from blender.(2 in total) But how do I access only the first one?
I think I'm looking for something like box.children[0].material.. or so. The index 0 is my outside material.
Thanks in advance!
I am loading a 3D model using 3 files I've been provided with:
example.obj
example.mtl
example.jpg
I am loading them in my Three.js script with this snippet:
var mtlLoader = new THREE.MTLLoader();
mtlLoader.setPath('./');
mtlLoader.load('example.mtl', function(materials) {
materials.preload();
var objLoader = new THREE.OBJLoader();
objLoader.setMaterials(materials);
objLoader.setPath('./');
objLoader.load('example.obj', function(obj) {
scene.add(obj);
}, onProgress, onError);
});
The model is displayed on screen and the textures applied, but incorrectly (textures are not properly assigned to each face, look rotated, etc). Looks like the texture mapping is incorrect. Since the snippet is so simple and everything seems to be set automatically I'm not sure what I could do to try to fix it. Any idea?
BTW, the files were exported from Zbrush.
Thanks in advance
Thanks for the comments but I finally found out what the problem was: Zbrush was exporting the textures upside down. I corrected them and the issue was fixed. Thanks again.
I need to display collada file (.dae) using three.js , i can load model but it display without textures , using this code
var loader = new THREE.ColladaLoader( loadingManager );
loader.options.convertUpAxis = true;
loader.load( './car.dae', function ( collada ) {
car = collada.scene;
car.material =
THREE.TextureLoader("../model/car_white.jpg");
i tried other codes ,only this code worked for model but without texture
need your support to add my texture.
Generally speaking, you can add textures to a model like this:
var textureLoader = new THREE.TextureLoader();
var texture = textureLoader.load('../model/car_white.jpg');
loader.load( './car.dae', function ( collada ) {
collada.scene.traverse(function (node) {
if (node.isMesh) {
node.material.map = texture;
}
});
});
Refer to the documentation for THREE.Material and THREE.TextureLoader for more information.
NOTE: As #gaitat mentioned in a comment, your texture may not be wrapped correctly on the model if they weren't designed for one another, and if the model isn't very simple. If that's the case, you probably need to add the texture in Blender (or other software) instead, where you can create UVs, and export the result.
I have an export of some .obj files and corresponding .mtl files. Textures are in .tga format in the same folder.
Here is the code I use to load all my .obj:
function addCar(modelPath, modelName) {
var mtlLoader = new THREE.MTLLoader();
mtlLoader.setPath(modelPath);
for (var i = 0; i <= 2; i++) {
loadObject(mtlLoader, modelPath, modelName, i);
}
}
function loadObject(loader, path, name, i) {
var objectName = name + i + '.obj';
loader.load(name + i + '.mtl', function (materials) {
materials.preload();
var objLoader = new THREE.OBJLoader();
objLoader.setMaterials(materials);
objLoader.setPath(path);
objLoader.load(objectName, function (object) {
scene.add(object);
}, function (xhr) {
onProgress(xhr, objectName)
}, onError);
});
}
The car is loaded, but not the textures. It appears all white, and there is no error in the console. I tried to add
mtlLoader.setTexturePath(modelPath);
but it didn't change anything.
I also tried to add
THREE.Loader.Handlers.add( /\.tga$/i, new THREE.TGALoader() );
before to call addCar function. When I do that, some warning appears in the console, but texture still doesn't appear.
In all examples I saw, textures are loaded automatically when using OBJLoader and MTLLoader, but I didn't any example using OBJLoader and MTLLoader with TGA textures. So I'm wondering if there is something to do to get it worked.
Any help would be appreciated.
PS: the files (.obj, .mtl and .tga) are exported from 3D max).
You'll have to use the TGALoader to load .tga files. You can find it here.
See the webgl_materials_texture_tga source for an example.
Is there a reason why you are using a .tga texture instead of .png? For most purposes they will give identical results, and .png will generally be smaller and can be natively decoded by the browser so you'll get better performance.
If the number of files is not very big: change the mtl file's content, make 'tga' to 'jpg', then I use photoshop to make every tga file to jpg file.
I am trying to export this https://www.dropbox.com/s/zz1g38xaci2ibod/sailor.blend?dl=1 Blender model using exporter from Three.js 73 (from github master branch).
But when I load it I see no texture:
var loader = new THREE.JSONLoader();
loader.load("assets/sailor.json",
function (geom, mat) {
console.log(mat);
var model = new THREE.Mesh(geom, mat[0]);
model.castShadow = true;
scene.add(model);
});
The model has two meshes (body and eyes) but looks like this exporter can export only one mesh... So for now I exported without eyes.
Exporter settings:
Exporter output file: sailor.json
io_three.export.log is empty with any logging level.
I'm not sure this will solve your problem but it might atleast give you a hint of where the problem is.
I compared my converted JSON files and compared to yours, and noticed that the JSON file that you use does not specify what texture the object should use.
Add:
"mapDiffuse" : "nameoftexture.png",
to your
"materials: [{
...,
...,
...
}]"
array.
Good luck.
EDIT
Your model seems to work with textures for me when I added this line to the materials property array.