Way to handle multple object as a single one in thee.js - javascript

I'm new to three.js. I need to handle multiple objects as a single one. In simple terms I need to render a kind of bas-relief:
a box geometry (the base)
an extruded image on top of it
and some text.
Each object has to have a different material but they has to act as a single one: location and rotation the same etc.
I'm still new to three.js so I don't know how to make a kind of composite pattern: with group? Joining geometry? Join mesh? What is the best way?
Right now I'm using everything in a group but.. it seems a bit slow.

You could nest your objects in an Object3D instance.
group = new THREE.Object3D(); //create a container
group.add( mesh1 ); //add a mesh with geometry to it
group.add( mesh2 );
scene.add( group ); //add the group to the scene
EDIT:
Release 69 added THREE.Group class and the release note say to use this instead of Object3D where possible, but I can not find any other documentation.
https://github.com/mrdoob/three.js/releases
group = new THREE.Group(); //create a container
group.add( mesh1 ); //add a mesh with geometry to it
group.add( mesh2 );
scene.add( group ); //add the group to the scene

Related

Three.js use multiple materials on one mesh

I am trying to understand how to add multiple materials to a mesh. I want to take the existing material and apply another slightly transparent material to my existing mesh. Right now, passing it as an array it just disappears. I know I am missing something, just not sure what that is. The end goal is so I can animate the opacity of the new material in/out over the existing one.
Original Material
const originalMaterial = child.material.clone();
New Material
const newMaterial = new THREE.MeshStandardMaterial({
name: 'New Mat',
map: newTexture,
emissiveMap: newTextureMap,
side: THREE.DoubleSide,
opacity: .5,
transparent: true
});
Combining them
child.material = [originalMaterial, newMaterial]
child.material.needsUpdate = true
WebGL doesn't allow for multiple materials on a single mesh. That's why the THREE.Mesh constructor only allows one geometry, and one material.
To do what you want, you could create two meshes, with one material's transparency set to 0.5. But more frequently you would just use a single mesh, and assign variations in opacity through the .alphaMap texture. This would give you more flexibility because you can have many more transparency values on a single object, without having to create new materials for each:
var textureLoader = new THREE.TextureLoader();
var alphaTexture = textureLoader.load("path/to/alpha.png");
mesh.material.alphaMap = alphaTexture;
mesh.material.transparent = true; // <- don't forget this!

Three.js - how to create custom shapes

I´m using Three.js and trying to create some custom shapes, similar to one that appears in a project from one of agencies using threejs:
three.js featured project esample
How did they generated these boxes with holes inside? (on that examples
boxes basically have only borders around and are empty inside).
As I saw in the code (I was trying to figure out myself) they use BoxGeometry but I have no idea how to accomplish that. Does anyone know or can give me any directions? It would be really helpfull as i´m stuck with this and have no idea on how to create them.
So in THREE.js Meshes represent any kind of 3D object. They combine Geometries and Shaders. Generally to create a mesh you call
var mesh = new THREE.Mesh( geometry, shader );
If you use any of the builtin shaders (also known as Materials [ MeshBasicMaterial, MeshLambertMaterial, etc]) they have a wireFrame boolean attribute that allows this functionality.
var geometry = new THREE.BoxGeometry( x, y, z ),
material = new THREE.MeshBasicMaterial( {
wireFrame: true, // This makes the object appear wireframe
color: 0xffffff // You can alter other properties
});
var box = new THREE.Mesh( geometry, material );
// You can also change it later
box.material.wireFrame = false;

How to change the normal of a PlaneGeometry in three.js?

I'm using Three.js to display planes, however I can't seem to find a way to change the normal of it. There's a Plane class that has a normal property so is there any way to use this instead of the PlaneGeometry one?
PlaneGeometry offers no means to change its normal, which is effectively always (0,0,1).
To make the plane geometry face in a different direction, you need to transform its vertices. This
is done by converting a Plane object to a transformation matrix and applying that
matrix to the PlaneGeometry. Here is code that generates a transformation matrix:
// Assumes that "plane" is the source THREE.Plane object.
// Normalize the plane
var normPlane=new THREE.Plane().copy(plane).normalize();
// Rotate from (0,0,1) to the plane's normal
var quaternion=new THREE.Quaternion()
.setFromUnitVectors(new THREE.Vector3(0,0,1),normPlane.normal);
// Calculate the translation
var position=new THREE.Vector3(
-normPlane.constant*normPlane.normal.x,
-normPlane.constant*normPlane.normal.y,
-normPlane.constant*normPlane.normal.z);
// Create the matrix
var matrix=new THREE.Matrix4()
.compose(position,quaternion,new THREE.Vector3(1,1,1));
// Transform the geometry (assumes that "geometry"
// is a THREE.PlaneGeometry or indeed any
// THREE.Geometry)
geometry.applyMatrix(matrix);
There is another option that perhaps can suit you. You can use lookAt method from the Mesh class. This method is inherited from Object3D class. You just need to specify the point where the plane will look. This way you can reuse your PlaneGeometry for other Mesh instances.
var geometry = new THREE.PlaneGeometry( 12, 12 );
var material = new THREE.MeshBasicMaterial( { color: 0x005E99 } );
var plane = new THREE.Mesh( geometry, material );
plane.lookAt(new THREE.Vector3(0.7, 0.7, 0.7));

Edgeshelper not updating position of mesh

I would like to draw a coloured box, including the edges (in a different colour)
This is the code I am using to create the box and edges. I have added them both to a object3D since I will have a number of differnt objects in the scene and would like to enforce encapsulation.
var mesh = new THREE.Mesh( geo, material );
var edge = new THREE.EdgesHelper( mesh, 0xffffff );
var container = new THREE.Object3D();
container.add(mesh);
container.add(edge);
scene.add(container);
The above posted code works and produces this:
But when I change the position of the parent object like so:
container.position.set(0,30,0);
Only the edges are moved. Why?
Adding .updateMatrix() to the container, mesh, or edges objects doesnt seem to produce different results.
How can the parent object be moved, included all of its children?
You need to add the helpers as children of the scene directly.
This is due to the following lines that appear in many of the helpers:
this.matrix = object.matrixWorld;
this.matrixAutoUpdate = false;
three.js r.70

How to access the each element individually in Three.js

I have created mesh and rendered " 10 " 3d objects using three.js?
how to access each object to perform scaling , rotation & all stuffs so there is a
need to get the div object individually?
help me to solve this issue ?
thanks !
You do not seem to be asking a real question. But rather asking for someone to teach you something. In the 'startup code' a SphereGeometry object is combined with a MeshBasicMaterial object in order to create the Mesh object which is your 3d object that you can then use to access/set the objects position, rotation, etc. Here are the lines of code I am referring to:
var geometry = new THREE.SphereGeometry( 75, 20, 10 );
var material = new THREE.MeshBasicMaterial( { color: 0xffffff, wireframe: true } );
var mesh = new THREE.Mesh( geometry, material );
Once you create mesh objects you need to add them to the scene with a call to scene.add(mesh). At this point you can set or get the rotation or position as such
mesh.position.x = 50;
mesh.rotation.z = Math.PI / 2 // rotations are in radians

Categories

Resources