Applying a material to an imported model [three.js] - three.js

Part of a project that I'm working on requires that I pull in an array of base64 images, then pull in imported models via THREE.JSONLoader(). If I keep these two types of assets apart, they both load without issue. However, if I try to apply the image as a material to the model, I get an error.
WARNING: Output of vertex shader 'vWorldPosition' not read by fragment shader
I realize that much of the time when you load in geometry, you need to run geometry.computeTangets(), but that isn't working. I thought perhaps there's another computation that might need to run prior to creating a mesh with the geometry and the material. Here's what I have:
var material = new THREE.MeshPhongMaterial({
map: THREE.ImageUtils.loadTexture(data.images[0]),
shininess: 4.0,
});
var loader = new THREE.JSONLoader();
loader.load("app/museum/geometry.json", function (geometry) {
geometry.computeTangents();
mesh = new THREE.Mesh(geometry, material);
mesh.scale.set(100, 100, 100);
mesh.position.y = 150;
mesh.position.x = 0;
scene.add(mesh);
});
I assume there's an additional setting or method that needs to be called, or perhaps there are attributes in the geometry.json that I need to set manually?

Related

Three JS - How do I change from Lambert to Phong on a material at runtime?

I tried setting "type" and then setting "needsUpdate", but it didn't change the type. I know I could make a new material, and then change every mesh that uses that material to use the new material, but I was hoping there was a way I could do it without iterating through every mesh.
You need to create a new material and have the mesh point to it.
mesh.material = new THREE.MeshPhongMaterial({ color: 0xffffff });
Check this fiddle: https://jsfiddle.net/29Lqeadx/.

THREE JS converting to BufferGeometry from Geometry not working when loading PLY file

I am loading a very complex 3D model from a PLY file (over 60Mb). In my project I need to use the orbit-control to move around the object. Obviously due to the large file the operation is painfully slow in some couputers. In order to speed up things a bit I am trying to convert my geometry into a Buffer geometry with the following lines of code:
this.loader.load('assets/data/GuyFawkesMask.ply', function (geometry) {
var bufferGeometry = new THREE.BufferGeometry().fromGeometry( geometry );
console.log(bufferGeometry);
// Create object
let object =
new THREE.Mesh(bufferGeometry,
new THREE.MeshPhongMaterial(
{
color: 0xFFFFFF,
//vertexColors: THREE.VertexColors,
shading: THREE.FlatShading,
shininess: 0
})
);
_this.add(object);
});
But I am getting the following error:
TypeError: Cannot read property '0' of undefined
at DirectGeometry.fromGeometry (three.module.js:12219)
at BufferGeometry.fromGeometry (three.module.js:14307)
at threed-viewer.component.ts:379
at index.js:52
at XMLHttpRequest. (three.module.js:29263)
at ZoneDelegate.webpackJsonp.818.ZoneDelegate.invokeTask (zone.js:367)
at Object.onInvokeTask (ng_zone.js:264)
at ZoneDelegate.webpackJsonp.818.ZoneDelegate.invokeTask (zone.js:366)
at Zone.webpackJsonp.818.Zone.runTask (zone.js:166)
at XMLHttpRequest.ZoneTask.invoke (zone.js:420)
Any idea?
Thank you,
Dino
Just posting prisoner849 comment (as an answer) for future reference:
If I get it right, looking into the source code of PLYLoader.js, the
geometry, which the callback function returns, is already of
THREE.BufferGeometry()

Three.js Mesh With Multiple Materials Disappears?

I'm trying to load a pretty simple model with two materials (applied per-face) in Three.js exported from Blender. The issue I'm running into is that with multiple materials applied via the code below the mesh disappears entirely, but I can easily use materials[0] or materials[1] in place of materials and see a solid object. My export settings from blender along with what it should look like are below and the json of the model is visible online here.
I tried your JSON file and it displayed just like your image. Here's the code I used (three.js r83):
var mesh = new THREE.Object3D();
var jsonLoader = new THREE.JSONLoader();
jsonLoader.load('/js/models/cube.json',
function (geometry, materials) {
mesh = new THREE.Mesh(geometry,
new THREE.MultiMaterial(materials));
scene.add(mesh);
}
);
http://www.threejsworld.com/tutorials/working-with-materials-in-threejs

explodeModifier not working for imported model in three.js

I am trying to do a face explode effect as seen in this example: http://threejs.org/examples/#webgl_modifier_tessellation
However the example uses THREE.TextGeometry and I am using an imported model using
THREE.JSONLoader();
loader.load( "models/animated/Brain-New_2154_ft.js", function ( geometry ) {
var material = new THREE.MeshLambertMaterial( {
color: 0x6249a3,
vertexColors: THREE.FaceColors,
morphTargets: true,
overdraw: 0.5
} );
How can I use an imported model for this effect? Do I have to convert the model to something before it's faces, vertices can be affected with the explodeModifier and TessellateModifier libraries? thanks!
You need to use the THREE.ExplodeModifier() which is not included in the core, you have to explicitly import it in (see line 140 in your example).
The ExplodeModifier just loops through the vertices array in your geometry so it should work with any model type that can be successfully imported.
var geometry = new THREE.PlaneGeometry(10,10,10,10);
var explodeModifier = new THREE.ExplodeModifier();
explodeModifier.modify( geometry );
This gives you an array of faces you can manipulate the same way you do the vertices

Loading multiple objects in Three.js from Blender

I have a quite complex shape (dressed girl) that in Blender is broken down into different objects and it's loaded into Three.js with the JSON loader (with a little hack I made, that uses zipped files instead of just JSON files, as there are a lot of vertices).
As I want to change dynamically the style of the dress from a Web page, I was wondering how I can show/hide different pieces (e.g. sleeves) in the scene.
I tried traversing the THREE.Mesh, but there are no children.
When I export from Blender with the JSON exporter, I don't see anything referring to the names of the objects in the JSON. Is the structure lost?
If you are using meshes containing lots of vertices, I would advise you to use the openCTM webGL loader instead of zip hacking. Here is a link to the loader : http://threejs.org/examples/webgl_loader_ctm.html
This mesh compression tool uses LZMA compression method and can reduce the size of your files by 93%...
Concerning the JSONLoader, using an array might help:
var meshes = [];
...
var loader = new THREE.JSONLoader();
var onGeometry = function(geom)
{
var mesh = new THREE.SceneUtils.createMultiMaterialObject(geom, [material]);
meshes.push( mesh );
...
scene.add(mesh);
};
loader.load("yourfile.js", onGeometry);
Hope this helps
It is possible to load an entire scene with several meshes from a json file exported from Blender and handle them separately!
You can follow the complete process of exporting a entire scene from Blender and the right way of handling the exported meshes on my answer of this post.
So, you can get the different meshes and manipulate them separately using the getObjectByName method. 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.
The loading code must look like this one:
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");
scene.add(surface);
scene.add(outline);
scene.add(mask);
} );
Besides, you can handle the multiple materials of single mesh using THREE.MeshFaceMaterial like in the following code:
var mat1 = new THREE.MeshLambertMaterial( { map: texture1 } );
var mat2 = new THREE.MeshLambertMaterial( { map: texture2 } );
var materials = [mat1, mat2];
var faceMat = new THREE.MeshFaceMaterial(materials);
mesh = new THREE.Mesh( geometry, faceMat );
scene.add( mesh );
Hope this helps :)

Resources