Add a 3D model to a exsisting THREE.Scene() - three.js

I create a scene, add a couple of boxes and I can move the camera with the keyboard just fine.
I want to add a 3D model. In several tutorials, I saw something like:
var jsonLoader = new THREE.JSONLoader();
jsonLoader.load( "test.js", function( geometry ) { createScene( geometry) } );
function createScene( geometry ) {
var mesh = new THREE.Mesh( geometry, new THREE.MeshLambertMaterial({color: 0xbbbbbb}) );
mesh.scale.set(10, 10, 10);
mesh.position.y = -350;
mesh.position.x = -650;
group.add(mesh);
}
But for the other element I wrote something like:
MovingCube = new THREE.Mesh(MovingCubeGeom, new THREE.MeshFaceMaterial());
MovingCube.position.set(0, 25, 0);
scene.add(MovingCube);
How can I add a 3D model from a .js converted .obj at my scene?

The first one loads the model from and external file which contains a JSON representation of the geometry and sends it to the createScene function as an instance of the THREE.Geometry class when the external file has finished loading.
The second one the geometry is already in the variable MovingCubeGeom.
The second example is basically the same as what is in the createScene function of the first example.
You don't need to convert an obj to js, you can just use the THREE.OBJLoader class

Related

three js: how to mix two scenes (one with bloom)

I have one Renderer object and two scene objects. One scene contains the objects that should not be processed by the unrealbloom post-processing pass and the other scene contains all “glowing” objects.
Now I thought I could do:
const THREED_Composer = new THREE.EffectComposer( THREED_Renderer );
const THREED_RenderPass = new THREE.RenderPass( THREED_Scene, THREED_Camera );
const THREED_RenderPassGlow = new THREE.RenderPass(
THREED_SceneGlow, THREED_Camera );
const THREED_BloomPass = new THREE.UnrealBloomPass(
new THREE.Vector2(window.innerWidth, window.innerHeight), 0.5, 0.5, 0.4);
//THREED_BloomPass.renderToScreen = false; ???
THREED_Composer.addPass( THREED_RenderPassGlow );
THREED_Composer.addPass( THREED_BloomPass );
THREED_Composer.addPass( THREED_RenderPass );
The intention was to first render the glowing objects and then render the non-glowing objects over them. I want the non-glowing objects to be able to obscure the glowing objects.
My animate function looks like this:
function animate()
{
if(GLOBAL_FocusLost)
return;
requestAnimationFrame(animate);
update();
THREED_Composer.render();
}
Ultimate goal:
I want to have glowing monolith in the midst of a room that can be obscured by all other objects.
I tried to read my way through the documentation but I think that I do not understand it enough.
Cheers. Any help is very much appreciated!

THREE.JS : Change material color behind PNG texture ? Assign 2 materials to a mesh imported from GLTF model?

I am trying to change the color of my 3D model "behind" the png texture I set (which includes transparency).
I have done a lot of researches, and i finally found an example with a cube which actually works, but I can't understand how to make that with my gltf 3D model (not a BoxGeometry).
METHOD :
Define an array of two materials,
first one is my png texture with transparency = true;
second one is a basic material with its plain color (the color i will be able to change later...)
var materialBack = new THREE.MeshBasicMaterial({color: 0xfadce6});
var materialTxt = new THREE.MeshBasicMaterial({map: mytexture,transparent: true});
var materials = [materialBack, materialTxt];
It works perfect with a cube :
var geometry = new THREE.BoxBufferGeometry();
geometry.clearGroups();
geometry.addGroup( 0, Infinity, 0 );
geometry.addGroup( 0, Infinity, 1 );
var cube = new THREE.Mesh( geometry, materials );
Problem : I can't figure out how to do the same when my model is actually an imported GLTF, and not a "BoxBufferGeometry". It looks like we can't assign an array to o.material :
var loader = new THREE.GLTFLoader();
loader.load(mymodel.glb, function(gltf) {
gltf.scene.traverse((o) => {
if (o.isMesh) {
o.material = materials;
}
scene.add(gltf.scene);
});
I also tried to extract geometry from gltf, then create a new mesh, but without success :
var loader = new THREE.GLTFLoader();
loader.load(mymodel.glb, function(gltf) {
var geometry = gltf.scene.getObjectByName("name").geometry;
mymesh = new THREE.Mesh(geometry,materials);
scene.add(mymesh);
});
Can someone please help ?

Three.js: Add a texture to an object just on the outside

I'm very new with Three.js and I'm trying to make a ring:
http://www.websuvius.it/atma/myring/preview.html
I have a background texture ( the silver one ) and another one with a text.
I want the text only on the ring external face.
This is part of my code:
var loader = new THREE.OBJLoader( manager );
var textureLoader = new THREE.TextureLoader( manager );
loader.load( 'assets/3d/ring.obj', function ( event ) {
var object = event;
var geometry = object.children[ 0 ].geometry;
var materials = [];
var backgroundTexture = textureLoader.load('img/texture/silver.jpg');
backgroundTexture.flipY = false;
var background = new THREE.MeshBasicMaterial({
map: backgroundTexture,
color: 0xffffff
});
materials.push(background);
var customTexture = textureLoader.load('img/text.png');
customTexture.flipY = false;
var custom = new THREE.MeshBasicMaterial({
map: customTexture,
transparent: true,
opacity: 1,
color: 0xffffff
});
materials.push(custom);
mesh = THREE.SceneUtils.createMultiMaterialObject(geometry, materials);
mesh.position.y=-50;
scene.add(mesh);
}, onProgress, onError );
It is possible?
Thanks
The reason behind your issue appears to be in your .obj file. Judging from a quick glance at the texture coordinates stored in the file, the inside of the ring uses the same part of the texture image as the outside of the ring.
Increasing the transparent parts of the image won't help. Neither will the attempts to stop the texture from repeating. Those would help if the texture coordinates were larger than 1 but this is not your case unfortunately.
However, there are several solutions:
Split the object in a 3D modeling software to two objects - outside and inside of the ring - and apply the texture only to the first one.
Adjust the UV coordinates of the object in a 3D modeling software.
Adjust the UV coordinates of the vertices programmatically after loading the object to Three.JS

Three.js images not loading from ThreeJs Json file

I have a threejs JSON object file generated from obj and mtl file using python convertor.
I am loading this js file using following code:
loader = new THREE.JSONLoader();
loader.load('3bhk_1635_perpsective/test.js', function (geometry, materials ) {
var mesh = new THREE.Mesh( geometry, new THREE.MeshFaceMaterial( materials ) );
geometry.computeFaceNormals();
scene.add(mesh);
}
);
Everything is loading except the images associated with the JSONObject. Please help me load all the images.
If loader gives you no error, try to adjust object position and camera position.
Otherwise you are adding the mesh to the scene before the model finishes loading.
Move add in the callback:
loader.onLoadComplete = function() {
scene.add(mesh);
}

Setting texture on mesh in three.js

I have a mesh that I load as a .dae (collada). However, my texture file is separate (as a PNG)
Currently, my loading code is
loader.load("./assets/map_tutorial.dae", function(collada) {
var terrain = collada.scene.children[0];
var texture = new THREE.ImageUtils.loadTexture("./assets/map_tutorial_tex.png");
terrain.rotation.x = Math.PI / 2;
terrain.rotation.y = Math.PI;
scene.add(terrain);
console.log("There are " + collada.scene.children.length + " meshes!");
});
However, I'm uncertain as to how to apply the texture to my mesh (terrain)
Thanks in advance!
You will definitely have to create new material object from your texture. Assuming you want lambert, it would be like this:
var material = new THREE.MeshLambertMaterial( { map:texture } );
I am not familiar with collada loader, but it seems that it already created a mesh for you. In this case I am not sure whether you can change material of this mesh. What should definitely work is to create new mesh from geometry that you loaded from .dae file and material that you created from png image.
var mesh = new THREE.Mesh( terrain.geometry, material );
scene.add( mesh );
I hope this helps, normally I use three.js native JSON model files where this approach is working. Difference is that THREE.JSONLoader gives you two objects for your usage: geometry and materials. Collada loader seems to provide you with already created mesh so try to change it's geometry if possible or "steal" the geometry from this mesh and create a new one like I did in the example.

Resources