invert mesh in three.js - three.js

How to invert a mesh using three.js
I had a mesh created using THREE.Mesh
var geometry = new THREE.ExtrudeGeometry( featurePts,extrudeSettings);
var mat = new THREE.MeshBasicMaterial( { color: color, wireframe: true, transparent: true } );
var mesh = new THREE.Mesh(geometry, mat );
But my shape looks inverted. Is there any way in Three.js to invert my shape?
shape used above is a list of THREE.Vector2
var featurePts = [];
featurePts.push(new THREE.Vector2 (550,107));

If you mean it looks inside out, try reversing your normals.

Related

Three.js: Can I Combine Multiple Mesh Objects into One Scene

Can I add more than one Mesh to the Scene in three.js? Code below shows my attempt to add a second Mesh to the Scene, however, it is not visible.
function setScene() {
var geometry = new THREE.BoxGeometry( 1, 1, 1 );
materials = new THREE.ShaderMaterial({
fragmentShader: Cam.fragmentShader,
vertexShader: Cam.vertexShader,
uniforms: Cam.uniforms,
side: THREE.BackSide,
transparent: true
});
var skyBox = new THREE.Mesh( geometry, materials );
Cam.scene.add( skyBox );
// Add second SkyBox to the Scene
THREE.ImageUtils.crossOrigin = '';
var loader = new THREE.TextureLoader();
loader.load('img/test-circle-sample.png', function ( texture ) {
var geometry = new THREE.PlaneGeometry( 1, 1 );
var material = new THREE.MeshBasicMaterial( {
map:texture,
opacity : 1,
side : THREE.DoubleSide,
transparent : false
} );
var sprite = new THREE.Mesh( geometry, material );
sprite.position.set(0,-3,7);
var rotation = new THREE.Matrix4()
.makeRotationAxis(new THREE.Vector3(1,0,0), 1.57);
sprite.rotation.setFromRotationMatrix(rotation);
Cam.scene.add(sprite);
});
}
Above code adds a panoramic image successfully, which I can see. I then attempt to add an overlay image to the scene that should stay on top of the panoramic image, but it remains hidden.
Note, if I do not add the first object (panoramic image) to the scene (i.e. remove Cam.scene.add( skyBox )) then the second overlay image appears fine.

How to apply a texture to a custom geometry in Three.js

I successfully applied a texture to a cube geometry with this:
var geometry = new THREE.CubeGeometry(10, 10, 10);
var meshMaterial = new THREE.MeshPhongMaterial({ transparent: false, map: THREE.ImageUtils.loadTexture('/app/images/wood.jpg') });
meshMaterial.side = THREE.DoubleSide;
var mesh = new THREE.Mesh(geometry, meshMaterial);
With this I get a nice textured cube like this:
Now I want to apply the same texture (512x512 jpg image) to a custom model I'm loading from an STL and this is what I get (in this case a pyramid):
This is the code:
loader.load(jsonParam.url, function (geometry) {
var meshMaterial = new THREE.MeshPhongMaterial({ transparent: false, map: THREE.ImageUtils.loadTexture('/app/images/wood.jpg') });
meshMaterial.side = THREE.DoubleSide;
var mesh = new THREE.Mesh(geometry, meshMaterial);
mesh.castShadow = false;
mesh.receiveShadow = true;
scene.add(mesh);
});
Why the texture is not being applied and I get only what seems to be an average of the texture colors?
You need UV mapping.
You can either edit the model in modelling software to add UV coordinates or maybe generate them as in the answers posted here.
I suppose another option would be to create your own shader that maps the texture to the model surface without using UV coordinates.

Using multiple materials with THREE.CylinderGeometry - create a wheel from cylinder

I want to create a wheel from cylinder (because importing 3D models makes it slower). But I cannot use multiple materials with cylinder geometry. It uses only the first material in an array.
var geometry = new THREE.CylinderGeometry(this.diameterWheel/2,this.diameterWheel/2,this.lastikGenisligi, 20, 4);
var materialArray = [];
materialArray.push(new THREE.MeshBasicMaterial( { color: 0x000000 }));
materialArray.push(new THREE.MeshBasicMaterial( { map: THREE.ImageUtils.loadTexture( '../textures/wheel.png' ) }));
materialArray.push(new THREE.MeshBasicMaterial( { color: 0x0000FF }));
materialArray.push(new THREE.MeshBasicMaterial( { color: 0xFF0000 }));
var material = new THREE.MeshFaceMaterial(materialArray);
var mesh = new THREE.Mesh(geometry, material);
What I want to create is a wheel which will have wheel.png wheel image on upper and bottom sides and black coverage on between them.
You need to loop through each face on the cylinder and tell which of the array materials the face uses.
geometry.faces[a].materialIndex = b;
Where a is the face index. You need to figure out yourself which face is which to choose the correct material through some system, ie. faces 0-10 with one color, etc. This depends on the cylindergeometry parameters. And b is the material index.

Three.js: mesh does not receive shadow and is not detected by intersectObjects

I have a WebGL Geometry Shape in Three.JS that is made by ExtrudeGeometry.
My problem is why it doesn't receive shadow (which is powered by THREE.SpotLight) or why Raycaster.intersectObject doesn't detect that!?
My shape is something like below:
var geometry = new THREE.ExtrudeGeometry(shape, extrudeSettings);
var mesh = THREE.SceneUtils.createMultiMaterialObject(geometry, [new THREE.MeshBasicMaterial({ color: color }), new THREE.MeshBasicMaterial({ color: color2, wireframe: true, transparent: false, wireframeLinewidth: 5 })]);
mesh.position.set(x, y, z);
mesh.rotation.set(rx, ry, rz);
mesh.scale.set(s, s, s);
mesh.castShadow = true;
mesh.receiveShadow = true;
scene.add(mesh);
It's ExtrudeGeometry natural, or what!?
This has nothing to do with the geometry.
THREE.SceneUtils.createMultiMaterialObject() achieves its effect by creating a parent object and two child meshes, each with the same geometry.
You need to set receiveShadow on the children, instead of the parent.
mesh.children[ 0 ].receiveShadow = true;
mesh.children[ 1 ].receiveShadow = true;
To get Raycaster.intersectObjects() to work on hierarchical objects, you need to pass in the recursive flag like so.
raycaster.intersectObjects( objects, true );
three.js r.59

Different material on back and frontside of extruded shape

I'm trying to apply different material on front and back sides of extruded shape, but cannot figure out where to put side: THREE.FrontSide and side: THREE.BackSide. Where they should be putted?
My relevant code part is:
var materialFront = new THREE.MeshPhongMaterial({ ambient: 0xffffff, map: frontTexture });
var materialSide = new THREE.MeshPhongMaterial({color: 0xE68A00, ambient: 0xffffff});
var extrusionSettings = {
amount: 10,
bevelEnabled: false,
bevelThickness: 0.2,
bevelSize: 0.2,
bevelSegments: 8,
material: 0,
extrudeMaterial: 1
};
var geometry = new THREE.ExtrudeGeometry(shapes, extrusionSettings);
var materials = [materialFront, materialSide];
var material = new THREE.MeshFaceMaterial(materials);
mesh = new THREE.Mesh(geometry, material);
UPDATE:
According to WestLangley's comment I succeeded in adding the different texture to backfaces:
// ...
var materials = [materialFront, materialSide, materialBack];
// ...
for ( var face in mesh.geometry.faces ) {
if (mesh.geometry.faces[ face ].normal.z == 1) mesh.geometry.faces[ face ].materialIndex = 2;
}
After you create your mesh geometry, and before the first call to render(), you have to change the materialIndex to 2 for the back faces. Then, add a third material in your material array.
You can identify the back faces by their face normals. Face normals for faces on the back of the geometry should all point in the same direction.
three.js r.58
Try using:
var materialFront = new THREE.MeshPhongMaterial({ ambient: 0xffffff, map: frontTexture, side: THREE.FrontSide });
var materialSide = new THREE.MeshPhongMaterial({ color: 0xE68A00, ambient: 0xffffff, side: THREE.BackSide });
even though you should probably lower your ambient contribution and give a color to the FrontSide material.
Then:
var materials = [materialFront, materialSide];
scene.add( THREE.SceneUtils.createMultiMaterialObject( geometry, materials ));

Resources