I am trying to load quite complex .3ds model into three.js using TDSLoader exactly the same way as in three.js/examples: https://github.com/mrdoob/three.js/blob/master/examples/webgl_loader_3ds.html
but what I get looks like this Result when it is supposed to look like this Loaded using https://3dviewer.net/. I can see that this online viewer uses three.js so it is possible. I also know that TDSLoader loads textures but does not map them for some reason (if I move texture out of the folder I get an load resource error). Code looks like this:
var loader = new THREE.TextureLoader();
var normal = loader.load('textures/normal.png');
var loader = new THREE.TDSLoader();
loader.setPath('textures/');
loader.load('textures/CAT_336D.3ds', function (object) {
object.traverse(function (child) {
if (child instanceof THREE.Mesh) {
child.material.normalMap = normal;
}
});
scene.add(object);
});
My model has 23 types of materials but the loader loads only 2 - black and yellow, you can see that glass, metal and others are missing. How do I map all textures and materials? Maybe it does not work because the model is too big? (over 160 meshes, around 30MB)
Related
I have a glb model which I am loading into my Vue project via Three js. I have managed to import several other models for practice, but the one I actually want on my page will not load. I have tried playing around with different scaling, positions, background colors (since the object is mostly black), and camera angles but I am not able to get it in frame no matter what I do. I am able to see the model perfectly in any regular gltf view, but I cannot see it in my project, what am I doing wrong here?
Edit: As a side note, I also tried changing the scale in blender, but that did not change the result.
const loader = new GLTFLoader();
let me = this; // must refer to the instance in vue in order to be added to the scene, have tested this with other models
loader.load(
'pantalla_ball_2.glb',
function(gltf) {
gltf.scene.traverse(function( node ) {
if ( node.isMesh ) { node.castShadow = true; }
});
gltf.scene.scale.set(1,1,1) // Have tried several scales from 0.01 to 200
me.scene.add(gltf.scene);
console.log("added") // added is successfully called every time
},
function(xhr) {
console.log(xhr);
},
function(err) {
console.log(err); // no errors appear in console
}
);
The object loading perfectly in 3d viewer below
Thanks to JP4 for his helpful comments, the issue was the ambient lighting was not strong enough to illuminate the object sufficiently enough to be seen. The axis helpers showed me that the object was there thanks to the gaps in the axes.
I know this is a well known question but I was not able to find a good answer.
My usage
I use three.js to display 3D models created through drone pictures (here an example).
The problem
I can't render heavy models (1M vertices, 2M faces) : Chrome or WebGl crashed.
What I tried
I used Threejs.org examples for all my tests to be sure that it was not my code that didn't work. I made my test on a x64 Chrome with --max_old_space_size=6144 flag.
Import model in .dae with ColladaLoader --> 2.5Go of RAM is used and Chrome crash (displaying "not enough memory")
Import model in .obj with OBJLoader + MTLLoader --> 2.8Go of RAM is used and WebGl crash
I red many posts about Three.js and memory allocation but many of them speak about remove an object from the scene
Possible solutions
I saw that .stl (binary) file are more compact, but as far as I know
there is no texture with these files, so I can't use it
Use BinaryLoader (which has GeometryBuffer output) but I need to convert .dae or .obj to binary files and I don't know how to do that
Load my model in multiple parts to not load in one shot ? But I didn't saw any example or posts with that kind of treatment
How to reproduce
For the code, I use basics examples on Threejs.org. For models :
If you want to try with .dae you can find on this folder a working example (WorkingModel.dae / .jpg) and the model who don't work (BigModel.dae / .jpg)
If you want to try with .obj you can find on this folder a working example (WorkingModel.dae / .jpg / .mtl) and the model who don't work (BigModel.dae / .jpg / .mtl)
Any ideas to load the big one ?
Thanks !
EDIT 1 :
I tried to put a breakpoint in the SuccessCallback to see if the overload of RAM is during the load or after. I was not able to hit the breakpoint, so the overload of RAM is before the SuccessCallback.
Then I went step by step in the ColladaLoader to find what is using so much RAM. Here is the "callstack" :
myCollada.load()
ColladaLoader.parse()
Geometry.parse()
Mesh.parse()
Source.parse (hit 3 times) = +400mo in RAM
Vertices.parse = +0mo in RAM
Triangles.parse = +1500mo in RAM
this.geometry3js.computeVertexNormals() = RAM go over 2600Mo and chrome crash
Could I do any other tests to find the reason of this problem ?
Thanks
Your textures are waaaay to big, and besides, you don't need them because your model has baked vertex colors, which includes baked lighting. Your model therefore does not require UVs eiher.
Use ColladaLoader2, and this pattern. It should work.
var loader = new THREE.ColladaLoader();
loader.load( 'BigModel.dae', function ( collada ) {
var dae = collada.scene;
dae.traverse( function( child ) {
if ( child instanceof THREE.Mesh ) {
child.geometry.removeAttribute( 'uv' ); // you don't need it
child.material = new THREE.MeshBasicMaterial( { // scene lights not required
vertexColors: THREE.VertexColors // you have them, use them
} );
scene.add( child );
}
} );
} );
three.js r.86
I'm currently using Three.js, version 71. I first create my models using blender, and then I export them as a JSON file. I then use THREE.JSONLoader to load the models into my scene using the following:
this.jsonLoader.load(pathToModelFile, function(geometry, materials) {
//...
});
The materials list only contains THREE.MeshPhongMaterial at index 0. This material seems to require a light source (like THREE.SpotLight for example) to be in my scene. Otherwise, my model will be black.
I basically just want to be able to load my models and not need to use a light source in order to see them. Therefore, I have the following questions, and answering any one of them would solve my problem:
Is there some flag or property in THREE.MeshPhongMaterial I could change that would allow my model to be seen without a light source?
If number 1 isn't possible, is there a way to use THREE.JSONLoader to give me a different kind of material that doesn't need a light source? For example, like THREE.MeshBasicMaterial?
Is there some way to export my models from blender that will already have the required flags/properties set (if possible)?
It sounds like I'm having the same problem that this guy mentions in the following link, but he never received an answer: Switch lighting of THREE.MeshPhongMaterial on / off dynamically
1 dont know, think not
2 yes
var jsonLoader = new THREE.JSONLoader();
jsonLoader.load(model, addthree1ToScene);
function addthree1ToScene( geometry, materials )
{
material = new THREE.MeshBasicMaterial(blahblah);
three1 = new THREE.Mesh( geometry, material );
scene.add( three1 );
console.log(three1);
}
3 yes, in Blender you can set a material type on mesh before exporting, or you can edit material variables in the exported file
EDIT:
Or most stupid way, it is possible to edit Material in expoted Json File, via discussion to this answer.
In this project I am working on I have several Collada models being displayed and then removed when not needed anymore. There seems to be a memory leak somewhere in the project and I am looking for ways to get it to run as smooth as possible as time is not on my sideā¦
I feel like I don't remove the meshes the right way and that this might cause some of the memory leakage I have.
I load the objects with LoadObject(level_1_character, "Assets/Level_1_Character.dae"); for example, where level_1_character is a Object3D. This calls the following function:
function LoadObject(name, url) {
var mesh, geometry, material, animation;
var loader = new THREE.ColladaLoader();
loader.options.convertUpAxis = true;
loader.load(url, function(col) {
mesh = col;
geometry = col.scene;
name.name = url.toString();
name.add(geometry);
});
}
I add the objects to the scene depending on the level through scene.add(level_1_character); and then remove it by doing the following:
level_1_character.traverse(function(child){
if (child instanceof THREE.Mesh) {
child.material.dispose();
child.geometry.dispose();
}
});
I am not sure if this actually fully removes the object though. It seems as though the objects still are present in memory. Any idea what I'm doing wrong here?
I have successfully animated a model in blender using bone animation technique and i have also textured it in blender using uv texturing. Then Using three.js export add-on in blender i have exported the model making sure uv and animation in checked in. However i don't know the technique to load the texture for the animated model. I viewed the morph normal example included in three.js where there is simple color texture is used using Lambert material. I have texture from external file. How do i load the texture. In js animated model file there is location for the texture and it is in same location. But it doesn't load. i used the face material technique as well.
the location for three.js example that i used to modify:
http://threejs.org/examples/webgl_morphnormals.html
Here is my code:
var loader = new THREE.JSONLoader();
loader.load( "bird_final.js", function( geometry, materials ) {
morphColorsToFaceColors( geometry );
geometry.computeMorphNormals();
// the old code to set color to the model
//var material = new THREE.MeshLambertMaterial( { color: 0xffffff, morphTargets: true, morphNormals: true, vertexColors: THREE.FaceColors, shading: THREE.SmoothShading } );
// my code
var meshAnim = new THREE.MorphAnimMesh( geometry, new THREE.MeshFaceMaterial( materials ) );
meshAnim.duration = 500;
meshAnim.scale.set( 20, 20, 20 );
meshAnim.position.y = 150;
meshAnim.position.x = -100;
scene1.add( meshAnim );
morphs.push( meshAnim );
} );
Except the documentation and some basic tutorials scattered across the web, is there anywhere i can learn three.js from ground up. like i know setting up scene and creating basic geometry stuffs but some detail info like loading textured model loading scenes etc.
I have created a series of commented examples for Three.js that illustrate features one at a time, starting with very basic features and progressing to more advanced ones (including loading models).
http://stemkoski.github.io/Three.js
Hope this helps!
Working with complex geometry, materials, textures, and animations are some of the hardest things to figure out in THREE.js - that's why we started there with our editor.
We make all of these easy. Export an FBX file (or OBJ/MTL, or Collada) from Blender. Bring it into a project in Verold Studio, then load it into your THREE.js program using our loader. Service is free for use, you pay us if you want enablement services or have a client who wants a maintenance/support agreement.
See the example below, couldn't be easier to bring your scene to THREE.js,
http://jsfiddle.net/rossmckegney/EeMCk/
// 1. Set and then start the animation :)
this.model.setAnimation("mixamo.com");
this.model.playAnimation(true);
//this.model.pauseAnimation();
// 2. Get the threedata for a model
console.log(this.model.threeData);
// 3. Move the model
this.tweenObjectTo(
this.model.threeData, // the model
new THREE.Vector3(1, 0, 0), // go to
new THREE.Quaternion(), // rotation
1, // time, in seconds
false, // smooth start
true); // smooth end
// 4. Clone the model
that = this;
this.model2 = this.model.clone({
success_hierarchy: function(clonedModel) {
that.veroldEngine.getActiveScene().addChildObject(clonedModel);
}
});