Collada model faces not displaying correctly in three.js - javascript

After importing a collada model into three.js, some of the model's faces are only visible from the inside of the model and not from the outside.
How can I fix the problem with the faces in question?
Is it possible to have the model's faces visible from both sides?

The reason it doesn't work properly is because your file has this double_sided flag set:
<effect id="material_3_4_0-effect" name="material_3_4_0-effect">
<profile_COMMON>
...
<extra>
<technique profile="GOOGLEEARTH">
<double_sided>1</double_sided>
</technique>
</extra>
</profile_COMMON>
</effect>
The three.js ColladaLoader doesn't look for this flag and set doubleSided on the material like it should. I've filed a bug for the issue.

To fix the faces being oriented incorrectly, load the model into a 3D modeling program like Blender and flip the normals of the faces that aren't displaying correctly.
Three.js meshes have a doublesided property you can set which will usually allow you to display the model with the faces visible from both sides.
Here's a short example of how to load a collada mesh and enable double-sided rendering.
var loader = new THREE.ColladaLoader();
loader.load('path/to/mesh.dae', loadModel);
function loadModel(geom) {
var mesh = new THREE.Mesh(geom, new THREE.MeshBasicMaterial());
mesh.doublesided = true;
scene.add(mesh);
}
And a live example: http://jsfiddle.net/r7Yq2/

Related

THREEJS - How to traverse all layers of model loaded with GLTFLoader?

How does one traverse a mesh loaded with GLTFLoader properly to walk through all layers?
I am trying to do a simple selective bloom pass on a model by traversing the model’s all parts, setting them to the bloom layer, and then rendering the combined original + bloomed layers. However, as we can see in the images below, only the yellow outer part of the model is actually found during the traversal, does anyone know how to extract the rest of the model for layer setting?
For reproduction, the model can be downloaded from here:
https://github.com/whatsmycode/Models/blob/master/PrimaryIonDrive.glb
This is the code I currently use:
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
let BLOOM_LAYER = 1;
new GLTFLoader().load( 'models/PrimaryIonDrive.glb', function ( gltf ) {
const model = gltf.scene;
model.traverse( function( child ) {
child.layers.enable(BLOOM_LAYER);
});
scene.add( model );
});
This is the resulting image, bloom is applied to the yellow outer rings only.
This is the bloom-mask only
The issue was that I had not added the point- and ambient lights to both layers. The bloomed object has properties that requires light to show color for all parts except for the emitting yellow rings. To fix the problem, I simply enabled the lights for both layers before adding the lights to the scene.
const pointLight = new THREE.PointLight(0xffffff);
pointLight.layers.enable(ENTIRE_LAYER);
pointLight.layers.enable(BLOOM_LAYER);
const ambientLight = new THREE.AmbientLight(0xffffff);
ambientLight.layers.enable(ENTIRE_LAYER);
ambientLight.layers.enable(BLOOM_LAYER);
scene.add(pointLight, ambientLight);

Accessing multiple objs using .getObjectById() with JSONLoader in Three.js

Is it possible to differentiate between the meshes within one .js file exported from blender and animate them separately using Three.js?
The cube I would like to select is named "Cube" loads properly. However, when I try to get it by Name or Id, it doesn't recognize the var item1.
loader = new THREE.JSONLoader();
loader.load('engine.js', function (geometry, materials) {
var mesh, material;
material = new THREE.MeshFaceMaterial(materials);
mesh = new THREE.Mesh(geometry, material);
mesh.scale.set(1, 1, 1);
var item1 = scene.getObjectByName("Cube");
item1.position.x = 15;
scene.add(mesh);
});
I found this post but it seems unresolved: Three.js load multiple separated objects / JSONLoader
What is the best approach to loading multiple meshes via JSONLoader? I'd prefer to load them together as one .js file and just select the ones I would like to animate.
Thanks for your help!
In your blender scene you need to name every mesh you want to access independently in three.js. Then you can use Object3D.getObjectByName() to access your mesh in three.js.
Yes, it is possible to load an entire scene with several meshes from a json file exported from Blender!
You can see the complete process described on my answer of the cited post
So, you can differentiate between the meshes using the getObjectByName method and manipulate them separately. But it is important to know that the loaded object isn't a Geometry anymore. It is labeled with the Scene type by now and it must be handled in a different way.
You must change the loading code for one like this:
loader = new THREE.JSONLoader();
loader.load( "obj/Books.json", function ( loadedObj ) {
var surface = loadedObj.getObjectByName("Surface");
var outline = loadedObj.getObjectByName("Outline");
var mask = loadedObj.getObjectByName("Mask");
mask.scale.set(0.9, 0.9, 0.9);
scene.add(surface);
scene.add(outline);
scene.add(mask);
} );
In the above code we can indeed animate the surface, outline and mask meshes independently.

UV texture's color is set to all model in collada loader of three js

first of all sorry for my bad english.
I have a problem with collada loader of three js, i have a cylinder in blender with a UV texture on it and i render it there everything is perfect but when i export it and load it in three js collada loader the color associated with image is applied to whole model like this.
The model in my browser
The original color of the model is red.
I am loading my model like this:
var loader = new THREE.ColladaLoader();
loader.options.convertUpAxis = true;
loader.load( 'untitled.dae', function ( collada ) {
var dae = collada.scene;
var skin = collada.skins[ 0 ];
dae.position.set(0,0,0);
dae.scale.set(25,25,25);
My collada file if u want to see it.
What i am doing wrong here? is there a problem the way i am exporting missing some attribute while exporting? i am new to web 3D programming.
what i did was i was not creating 2 different materials 1 for color and other for the texture and i shifted to obj/mtl from collada importer and it solved my problem also remember to clip the image texture in blender texture settings under image sampling.

THREE.js Imported model doesn't apply face textures

I'm trying to import a model that was exported from blender using the THREEJS exporter.
So far the model loads and appears in my scene with the materials being applied correctly (Car is yellow as it's supposed to be and the glass is transparent as it's supposed to be.)
But it's not applying my textures to the car which are saved in .tga form.
If I DO NOT include the textures in my server directory where the model is i will get this error:
http://novsstudio.com/race/model//wheel.tga 404 (Not Found)
Notice it has two /'s after model.
I'm not sure if this is my problem, and I don't know how to fix it.
But when I upload my textures to /race/model/ all the textures are DOWNLOADED as seen in the Network tab in Chrome but are not applied to the model.
I believe maybe threejs cant find them because it's looking for them in /race/model//?
Here's my code to import the model:
var jsonLoader = new THREE.JSONLoader();
jsonLoader.load( "model/car.js", addModelToScene );
// addModelToScene function is called back after model has loaded
var ambientLight = new THREE.AmbientLight(0xFFFFFF);
scene.add(ambientLight);
ambientLight.position.set(0, 500, 200);
function addModelToScene( geometry, materials )
{
var material = new THREE.MeshFaceMaterial( materials );
android = new THREE.Mesh( geometry, material );
android.scale.set(10,10,10);
scene.add( android );
}
To see a live example of what it looks like now go to http://novsstudio.com/race
You can also view the source there too to get the full source and you can also browse my directories to see where i have all my files at http://novsstudio.com/race/model
Thank for the help let me know if you need more information.
Tip: You can move the camera at my website by clicking and holding/dragging to see the whole model.
See the TGALoader located in the examples/js/loaders directory.
Example: http://threejs.org/examples/webgl_materials_texture_tga.html.
Alternatively, you can convert you TGA files to PNGs and modify the JSON file accordingly.
EDIT: Updated to three.js r.68

Three.js skinned animation mesh disappears when material skinning is true

I've exported an animated model from Blender which doesn't seem to have any issue instantiating. I'm able to create the THREE.Animation and model, but I was finding there was no animation. I realized I needed to set skinning true on each material, but when I do that the entire mesh goes missing.
Below is my (quick and messy) code trying to get everything to work.
function loadModel() {
var loader = new THREE.JSONLoader();
loader.load('assets/models/Robot.js', function(geom, mat) {
_mesh = new THREE.Object3D();
_scene.add(_mesh);
geom.computeBoundingBox();
ensureLoop(geom.animation);
THREE.AnimationHandler.add(geom.animation);
for (var i = 0; i < mat.length; i++) {
var m = mat[i];
//m.skinning = true; <-- Uncommenting this makes the model disappear
//m.morphTargets = true; <-- This causes all sorts of WebGL warnings
m.wrapAround = true;
}
var mesh = new THREE.SkinnedMesh(geom, new THREE.MeshFaceMaterial(mat));
mesh.scale.set(400, 400, 400);
mesh.position.set(0, -200, 0);
mesh.rotation.set(Utils.toRadians(-90), 0, 0);
_mesh.add(mesh);
_robot = mesh;
Render.startRender(loop);
var animation = new THREE.Animation(mesh, geom.animation.name);
animation.JITCompile = false;
animation.interpolationType = THREE.AnimationHandler.LINEAR;
animation.play();
});
}
I believe I'm updating the AnimationHandler correctly in my loop
function loop() {
_mesh.rotation.y += 0.01;
var delta = 0.75 * _clock.getDelta();
THREE.AnimationHandler.update(delta);
}
In the section metadata of the exported JSON file the number of morphTargets and bones are both greater than 0?
I think that you followed the example here:
http://threejs.org/examples/#webgl_animation_skinning_morph
in which the animated model uses Morph Target and Skeletal Animation (see Wikipedia for the theoretical concepts).
If the animated model uses only Skeletal Animation as in this example http://alteredqualia.com/three/examples/webgl_animation_skinning_tf2.html
you have to instantiate a THREE.SkinnedMesh Object and then set only the m.skinning property to true.
I was having the same problem just now. What worked for me was to remake the model with applied scale and have keyframes for LocRotScale, not just location.
lately, I've encoutered a similar issue of mesh disapearing while exporting blender skinning animation to json. It turned out, the mesh I was using had double vertex (one vertice hidding another). All looks good While creating the vertex groups and the animations in blender, but when I imported the mesh via three.js, it kept disapearing as soon as the animation started. In other words, If 1 vertice from your mesh is omitted from the vertex groups, you will experience this disapearing behavior. To prevent this issue, I now use the "remove doubles" function from blender to validate the mesh integrity before exporting it to json. You might have encountered the same issue and redoing your mesh work fix it... Anyways, the question is pretty old, but the topic is still valid as of today, so I hope this fresh info will help someone out there...
Peace INF1

Categories

Resources