THREE.DoubleSide doesn't work with THREE.MeshLambertMaterial and custom geometry - three.js

I'm trying to make a double-sided mesh with THREE.MeshLambertMaterial, but only the front side is shaded. It works fine when I use THREE.MeshBasicMaterial. I am using the THREE.WebGLRenderer, version 57.
Here's a simplified example with a rectangle:
var rectWidth = 100, rectLength = 100;
var geometry = new THREE.Geometry();
geometry.vertices.push(new THREE.Vector3(0, rectWidth, 0));
geometry.vertices.push(new THREE.Vector3(rectLength, rectWidth, 0));
geometry.vertices.push(new THREE.Vector3(rectLength, 0, 0));
geometry.vertices.push(new THREE.Vector3(0, 0, 0));
geometry.faces.push(new THREE.Face4(0, 1, 2, 3));
// MeshBasicMaterial works
var material = new THREE.MeshLambertMaterial({
color: 0xCC0000,
side: THREE.DoubleSide,
});
geometry.computeFaceNormals();
geometry.computeVertexNormals();
var rect = new THREE.Mesh(geometry, material);
scene.add(rect);
What am I doing wrong? I found http://mrdoob.github.com/three.js/examples/webgl_performance_doublesided.html, which shows that THREE.DoubleSide works with THREE.MeshPhongMaterial (which also didn't work in my case). The example uses a built-in geometry though, whereas I am building a custom one, so I suppose I am missing something there.

Related

How may i use three.js to create a fatline

Currently, I'm working on a three.js project where i must use a lot of points to drow a fat line ;I had use the lineWidth property of THREE.LineBasicMaterial,but it is not work; My big question now is how to to do it?
this is the code
createLine_old() {
const material = new THREE.LineBasicMaterial({
color: 0x0000ff,
linewidth: 10
});
const points = [];
points.push(new THREE.Vector3(-10, 0, 0));
points.push(new THREE.Vector3(0, 10, 0));
points.push(new THREE.Vector3(10, 0, 0));
const geometry = new THREE.BufferGeometry().setFromPoints(points);
const line = new THREE.Line(geometry, material);
scene.add(line);
}
At last, any help would be appreciated;

Get world position of plane

I'm very new to three.js so I'm sure I'm miss-understanding something here.
I've created a plane in the following way:
var planeGeom = new THREE.PlaneGeometry(0.2, 0.2);
planeGeom.rotateX(-Math.PI / 2);
var plane = new THREE.Mesh(planeGeom, new THREE.MeshBasicMaterial({color: 0xffff00, side: THREE.DoubleSide}));
plane.position.set(0, 0.1, 0);
scene.add(plane);
var mathPlane = new THREE.Plane();
planePointA.copy(plane.geometry.vertices[plane.geometry.faces[0].a]);
planePointB.copy(plane.geometry.vertices[plane.geometry.faces[0].b]);
planePointC.copy(plane.geometry.vertices[plane.geometry.faces[0].c]);
plane.localToWorld(planePointA);
plane.localToWorld(planePointB);
plane.localToWorld(planePointC);
mathPlane.setFromCoplanarPoints(planePointA, planePointB, planePointC);
var helper = new THREE.PlaneHelper( mathPlane, 1, 0xffff00 );
scene.add( helper );
Why is my PlaneGeometry object and Plane positioned differently? Why doesn't .localToWorld() get the world position of the plane?
https://jsfiddle.net/sek0yzLp/
Use .updateMatrixWorld() on the plane after setting its position:
plane.position.set(0, 0.1, 0);
plane.updateMatrixWorld();
scene.add(plane);

[three.js]THREE.Geometry : can't apply textured material

I created a hexagon with THREE.JS, it works with a basic material with a color, but i can't make it works with a texture... When i set up a textured material, the object isn't rendered at all.
I had the same problem with a bufferGeometry, but i solved the issue by setting geometry.addAttribute('uv'..., but this time, looks like it's not a uvs issue.
Here's the JS code :
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera( 75, window.innerWidth/window.innerHeight, 0.1, 1000 );
var renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
// Adding light
scene.add( new THREE.AmbientLight( 0x444444 ) );
// SPOT LIGHT
var pXL1 = 3; var pYL1 = 1; var pZL1 = 2;
var LightGeometry1 = new THREE.BoxGeometry( 0.1, 0.1, 0.1 );
var LightMaterial1 = new THREE.MeshBasicMaterial( { map: new THREE.ImageUtils.loadTexture( "textures/default.jpg" ) } ); // this one is well textured !!!!
var LightCube1 = new THREE.Mesh( LightGeometry1, LightMaterial1 );
LightCube1.position.set(pXL1, pYL1, pZL1);
scene.add( LightCube1 );
var light1 = new THREE.DirectionalLight( 0xffffff );
light1.position.set( pXL1, pYL1, pZL1 ).normalize();
scene.add(light1);
var geometry = new THREE.Geometry();
geometry.vertices.push(new THREE.Vector3(-0.866 , 0.5,1));
geometry.vertices.push(new THREE.Vector3(-0.866 , -0.5 ,1));
geometry.vertices.push(new THREE.Vector3(0, -1 ,1));
geometry.vertices.push(new THREE.Vector3(0.866, -0.5 ,1));
geometry.vertices.push(new THREE.Vector3(0.866,0.5 ,1));
geometry.vertices.push(new THREE.Vector3(0, 1 ,1));
geometry.faces.push(new THREE.Face3(1, 2, 3, new THREE.Vector3(0, 0, 1)));
geometry.faces.push(new THREE.Face3(1, 3, 4, new THREE.Vector3(0, 0, 1)));
geometry.faces.push(new THREE.Face3(4, 0, 1, new THREE.Vector3(0, 0, 1)));
geometry.faces.push(new THREE.Face3(4, 5, 0, new THREE.Vector3(0, 0, 1)));
geometry.faceVertexUvs[0] = [];
geometry.faceVertexUvs[0].push( THREE.Vector2(0,5), THREE.Vector2(0.933,0.2835), THREE.Vector2(0.933,0.7165));
geometry.faceVertexUvs[0].push( THREE.Vector2(0,5), THREE.Vector2(0.933,0.7165), THREE.Vector2(0.5,1));
geometry.faceVertexUvs[0].push( THREE.Vector2(0.5,1), THREE.Vector2(0.067,0.2835), THREE.Vector2(0,5));
geometry.faceVertexUvs[0].push( THREE.Vector2(0.5,1), THREE.Vector2(0.067,7165), THREE.Vector2(0.067,0.2835));
var hexagon_texture = new THREE.ImageUtils.loadTexture( "textures/default.jpg" );
hexagon_texture.wrapS = THREE.RepeatWrapping;
hexagon_texture.wrapT = THREE.RepeatWrapping;
hexagon_texture.repeat.set(1,1);
var hexagon_material = new THREE.MeshBasicMaterial( { color: 0xff0000} );
//var hexagon_material = new THREE.MeshPhongMaterial( { ambient: 0xffffff, specular: 0x555555, shininess: 50, map:hexagon_texture, side: THREE.DoubleSide } );
//var hexagon_material = new THREE.MeshBasicMaterial( { map: new THREE.ImageUtils.loadTexture( "textures/default.jpg" ) } );
var hexagon = new THREE.Mesh( geometry,hexagon_material );
scene.add(hexagon);
camera.position.z = 5;
controls = new THREE.OrbitControls( camera, renderer.domElement );
var render = function () {
requestAnimationFrame( render );
renderer.render(scene, camera);
};
render();
As it, it works and i have a red hexagon. But if i uncomment one of the var hexagon_materual = ..., then the hexagon isn't rendered.
What am i missing ?
Thank you

Smooth Ring 3D in three.js

I want to draw a ring with the help of ExtrudeGeometry.
Ring3D = function(innerRadius, outerRadius, heigth, Segments) {
var extrudeSettings = {
amount: heigth,
bevelEnabled: false,
curveSegments: Segments
};
var arcShape = new THREE.Shape();
arcShape.moveTo(outerRadius, 0);
arcShape.absarc(0, 0, outerRadius, 0, Math.PI * 2, false);
var holePath = new THREE.Path();
holePath.moveTo(innerRadius, 0);
holePath.absarc(0, 0, innerRadius, 0, Math.PI * 2, true);
arcShape.holes.push(holePath);
var geometry = new THREE.ExtrudeGeometry(arcShape, extrudeSettings);
var material = new THREE.MeshPhongMaterial({
color: 0x00ffff
});
var mesh = new THREE.Mesh(geometry, material);
mesh.rotation.x = Math.PI / 2;
mesh.position.y = heigth / 2;
var object = new THREE.Object3D;
object.add(mesh);
return object;
}
The resulting figure has visible scars. And the cylinder and torus such scars not. How to get rid of them? Example here.
with geometry.computeVertexNormals();
var shape = new THREE.Shape();
shape.moveTo(0, 0);
shape.lineTo(0, 10);
shape.quadraticCurveTo(35, 30, 0, 50);
shape.lineTo(0, 60);
shape.quadraticCurveTo(48, 30, 0, 0);
var extrudeSettings = {
amount : 20,
steps : 10,
bevelEnabled: false,
curveSegments: 8
};
var geometry = new THREE.ExtrudeGeometry( shape, extrudeSettings );
var mesh = new THREE.Mesh( geometry, new THREE.MeshPhongMaterial( { color: '0x804000' ,transparent: true,opacity: 0.2} ) );
scene.add( mesh );
You need to .computeVertexNormals() from your geometry. But it seems there is some issue (with a solution) explained here: https://github.com/mrdoob/three.js/issues/323. I am not sure if it will work in your case.
I have found a comment in the code of ExtrudeGeometry:
this.computeFaceNormals();
// can't really use automatic vertex normals
// as then front and back sides get smoothed too
// should do separate smoothing just for sides
//this.computeVertexNormals();
So it seems it is not supported now :(

Which array is being indexed by the values in geometry.faces.materialIndex?

I want to create my own mesh (THREE.js, using CanvasRenderer) by defining the geometry as a set of vertices and faces:
geometry = new THREE.Geometry();
...
geometry.vertices.push(new THREE.Vector3(0, 0, 0));
geometry.vertices.push(new THREE.Vector3(1, 0, 0));
geometry.vertices.push(new THREE.Vector3(2, 0, 0));
...
...
geometry.faces.push(new THREE.Face3(1, 4, 3));
geometry.faces.push(new THREE.Face3(1, 2, 4));
geometry.faces.push(new THREE.Face3(3, 4, 5));
...
geometry.computeFaceNormals();
Because I want my mesh to have different color faces, I generate an array of materials. As I have read in some tutorials, I call this array geometry.materials:
geometry.materials = [
new THREE.MeshBasicMaterial({ color: 0xFF00A0 }),
new THREE.MeshBasicMaterial({ color: 0x00FF00 }),
new THREE.MeshBasicMaterial({ color: 0x0000FF }),
...
];
And then, I assign the indices to geometry.faces[i].materialIndex:
geometry.faces[0].materialIndex = 0;
geometry.faces[1].materialIndex = 2;
geometry.faces[2].materialIndex = 1;
...
Finally, I generate the mesh and add it to the scene:
mesh = new THREE.Mesh(geometry, new THREE.MeshFaceMaterial());
scene.add(mesh);
Well, this code is not working. All I get is an invisible mesh (no faces can be seen). My questions are:
Is 'geometry.materials' the default variable name to define material arrays? Which array are the values in faces[i].materialIndex referring to?
Why is my code not working?
Tutorials are almost always out-of-date. Study the three.js examples instead.
If you are using tutorials, be sure to also check the Migration wiki: https://github.com/mrdoob/three.js/wiki/Migration.
Geometry no longer has a materials property.
Instead of adding the materials array to geometry, do this:
mesh = new THREE.Mesh( geometry, new THREE.MeshFaceMaterial( materials ) );
three.js r.53

Resources