Three.js texture on material - javascript

I'd like to apply a custom image texture (.bmp or .jpg) on a material loaded from Blender and used in my project via the JSONLoader method.
There is no bug but the render of the material with the texture is bad looking.
You can see it here: http://image.noelshack.com/fichiers/2014/18/1399215240-stack.png
I'd like to get rid of these "rays" on my material. Here is the code I use to load my material/texture:
var texture = THREE.ImageUtils.loadTexture('/Game/models/textures/black.jpg');
var currentMaterial = new THREE.MeshBasicMaterial({ map: texture });
var currentModel = new THREE.Mesh(geometry, currentMaterial);
The "geometry" variable is the result of the callback of the JSONLoader.Load method.
I'd like to know if the problem comes from the image texture or from the code. And what is the best way to load a material created in Blender and exported as a JS file and loaded with the JSONLoader. I'm not sure if I use the best method when I use the "THREE.MeshBasicMaterial" constructor.
Thanks

Related

Three.js texture is not loading - what would cause this?

I am trying to create a scene using .obj and .mtl files exported from blender. The object is literally just a rectangle (it needs to be a .obj file. more objects will be added to create a scene) I am able to see the material load, but cannot see the texture being applied in chrome or firefox.
the mtl file text
the obj file text
Here is the javascript code:
const obj_loader = new THREE.OBJLoader(),
mtl_loader = new THREE.MTLLoader();
// uses example of OBJ + MTL from three.js/examples
mtl_loader
.setTexturePath('bar/')
.setPath('bar/')
.load('floor.mtl', (materials) => {
materials.preload()
obj_loader
.setMaterials(materials)
setPath('bar/')
.load('floor.obj', (object) => {
// everything returns status 200!
// material is being applied but no texture
scene.add(object);
})
});
project file structure
Checking the console, requests for the mtl, obj, and image files are returning 200 status codes
but the model renders without texture
No errors are in the console at all. What would cause this issue in Three.js? I suspect something is wrong with the .obj or .mtl but I cannot find the problem. (the file paths are correct based on the logged ajax request).
This may be due to the .preload() method not being called on the materials object returned in the material load callback. The preload() method basically creates the material objects loaded by the MTLLoader.
Consider the following updates, with this method call added:
const mtl_loader = new THREE.MTLLoader();
mtl_loader.setTexturePath('bar/');
mtl_loader.setPath('bar/');
mtl_loader.load('floor.mtl', function(materials) {
// Add this (see link below for more detail)
materials.preload()
const obj_loader = new THREE.OBJLoader();
obj_loader.setMaterials(materials);
obj_loader.setPath('bar/');
obj_loader.load('floor.obj', function(object) {
scene.add(object);
})
});
Here is a link to the THREE source code which shows the inner workings of .preload() - hope this helps!
It turned out to be an issue with the UV mapping of the texture. In Blender, you can create a texture, and Blender will show the texture in 'render' mode, even if the UV map is not set (It will wrap automatically).
Blender showing render, even without UV Map
This was especially frustrating because I had these settings when exporting the file:
export settings for OBJ
The MTL and OBJ file appeared to have all the content in it, but by manually UV mapping the texture (instead of using a simple repeat in the "texture" menu) the issue was resolved when I exported again.
UV/Image editor needed to be used
Sorry for any confusion that may have caused. I hope it helps anyone who has the same issue exporting from Blender.

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.

Can't create a mesh from a loaded Three.js object

I used clara.io to export a model with four textures on it in the ThreeJS Object format. It results in a .json file. I am trying to load it and have it display correctly. If I do the following(taken directly from the clara.io exporting help), it loads and displays but without textures:
var loader = new THREE.ObjectLoader();
loader.load( "wsc3.json", function(obj){
scene.add(obj);
});
One thing that I have found, is, in reference to using a different kind of loader, it should be possible to convert the loaded object into a THREE.Mesh, get the textures, and then apply them to the mesh. I have a working example of this:
loader = new THREE.JSONLoader();
loader.load("wsc3.js", function(geometry, materials){
// get the materials loaded from the file
var materialsFromFile = new THREE.MeshFaceMaterial(materials);
// create our mesh with the loaded geometry and materials
mesh = new THREE.Mesh(geometry, materialsFromFile);
scene.add(mesh);
});
The problem with using the JSONLoader is that the model I am exporting has subparts, and when the .js file that the JSONLoader uses is exported, it loses the model hierarchy(I checked the .js file itself and none of the subparts are there. It is just a huge list of vertices). If I have a look at the .json file that clara.io exports, I can see the various subparts listed, so I would guess that I need to use this format.
I have looked around and seen that there is the suggestion to just create a new mesh from the obj that is generated by the ObjectLoader. Something like this:
var loader = new THREE.ObjectLoader();
loader.load( "wsc3.json", function(obj){
// get the geometry from the obj
var geometry = obj.geometry;
// get the materials from the obj
var materials = obj.materials;
mesh = new THREE.Mesh(geometry, materials);
scene.add(mesh);
});
Unfortunately, this doesn't work. Nothing displays. I can't figure out what I am doing wrong. Is there a format that Three.js will load, that not only brings the textures but the hierarchy as well?

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

Parameterizing and editing a model using ThreeJS or X3DOM in the browser

I am using ThreeJs to render some STL files in the browser.
I am trying to figure out if I can add parameters to these models, so that I can edit these models using ThreeJs or X3DOM.
For example I have a cube and I want to add a text parameter to this cube.
When the text parameter is passed to ThreeJS, it embosses the text on the cube at a specific location.
I don't mind converting the STL files to the ThreeJS model Js file or X3D files as long as I can parameterize the rendering to add text to the basic structure.
I want to know if anyone has had experience doing this kind of 3D parameterization.
Is this possible in ThreeJS or X3DOM?
If yes, then is there any documentation that I could use to achieve this?
If these libraries cannot handle this case, then are there any other libraries which can achieve the same?
Edit
My question is more about how I can add parameters to the model itself. Can we have parameters in ThreeJS models themselves, which ThreeJS understands out of the box. Let me ignore the text example, if I consider a simple cube in a model file, is there a way to make Threejs understand its side length as param from the model, and any changes to this param automatically gets reflected into the visualization. I.e. IF I change the side length from 1 to 3, Threejs renders a larger cube.
I'm not sure it answers your question, but personally I would create a subclass of an empty 3D object, and apply your effects programmatically, after the base model is loaded.
Here's how I do with three.js (ideally, this is in a separated file) :
var EmbossedCube = function( text, onLoaded ) {
THREE.Object3D.apply(this);
var self = this;
var loader = new THREE.STLLoader();
loader.addEventListener( 'load', function ( event ) {
var material = new THREE.MeshPhongMaterial( { ambient: 0xff5533 } );
// apply effects on the material, or the geometry
// according to `text`
var mesh = new THREE.Mesh( event.content, material );
// transform the mesh locally if needed
self.add( mesh );
onLoaded && onLoaded( self );
} );
loader.load( './model.stl' );
};
EmbossedCube.prototype = Object.create( THREE.Object3D.prototype );
// methods of EmbossedCube
EmbossedCube.prototype.constructor = THREE.Object3D;
Then you can create such an object, and add it to your scene:
var cube = new EmbossedCube("beep", function(obj){
// you can translate/rotate the object if needed
scene.add( obj );
});
It could be not the simplest way to do it, but I think it offers a good reusability on the long term.
Explore the va3c viewer, which has options for opening files from REVIT, grasshopper etc.
You might try opening your files first in Rhino + GH, then creating those parameters that you need and then importing it using va3c.
This is a hunch and I cannot try until you give an actual file with details about the usecase.
Tell me if this works. ;)

Categories

Resources