Texture appears black on custom mesh but transparency is right - three.js

I created a mesh with vertices and uvs from another geometry like this:
var geom = mesh.geometry;
var projectGeometry = new THREE.Geometry();
var faces = [];
for(var i = 0; i < geom.faces.length; i++){
var verts = [geom.faces[i].a, geom.faces[i].b, geom.faces[i].c];
var uvs = [geom.faceVertexUvs[0][i][0], geom.faceVertexUvs[0][i][1], geom.faceVertexUvs[0][i][2]];
var pts = [];
var uvpts = {};
var uv = [];
var vec = geom.vertices[verts[v]].clone();
for(var n = 0; n < 3; n++){
uv.push(new THREE.Vector2( (vec[n].x + 1) / 2, (vec[n].y + 1) / 2));
uvpts = { x: 2*geom.faceVertexUvs[0][i][n].x - 1, y: 2*geom.faceVertexUvs[0][i][n].y - 1, z: 0};
projectGeometry.vertices.push( uvpts );
}
projectGeometry.faceVertexUvs[0].push(uv);
var newFace = geom.faces[i].clone();
newFace.a = decalGeometry.vertices.length - 3;
newFace.b = decalGeometry.vertices.length - 2;
newFace.c = decalGeometry.vertices.length - 1;
var newUvFace = new THREE.Face3( newFace.a, newFace.b, newFace.c );
newUvFace.normal = {x: 0, y: 0, z: 1};
newUvFace.color = {r: 1, g: 1, b: 1};
newUvFace.vertexNormals.push({x: 0, y: 0, z: 1});
newUvFace.vertexNormals.push({x: 0, y: 0, z: 1});
newUvFace.vertexNormals.push({x: 0, y: 0, z: 1});
projectGeometry.faces.push(newUvFace);
}
The I added the mesh to the scene like this:
var mesh = new THREE.Mesh(projectGeometry, material.clone());
scene.add(mesh);
With a material defined like this:
texture = THREE.ImageUtils.loadTexture("tex.png");
material: new THREE.MeshPhongMaterial({
side: THREE.DoubleSide,
color: 0xffffff,
map: texture,
polygonOffset: true,
polygonOffsetFactor: -4,
transparent: true,
depthWrite: false,
shininess: 150,
specular: 0xffffff
});
The texture has some transparency, so I can see that the "shape" of the texture is right but no color is applied. It is all black.

It was a light problem. As I have transparency in my texture material, I used the PhongMaterial. I configured a DirectionalLight to illuminate the scene. For some reason the texture colors were rendered black. I changed the light to AmbientLight and everything was rendered fine.

Related

Dim reflection of ThreeJS directional light on object

I have a ThreeJS directional light with the following configuration:
const sunLight = new THREE.DirectionalLight(new
enter code hereTHREE.Color('#FFFFFF').convertSRGBToLinear(), 3.5);
sunLight.position.set(10, 20, 10);
sunLight.castShadow = true;
sunLight.shadow.mapSize.width = 512;
sunLight.shadow.mapSize.height = 512;
sunLight.shadow.camera.near = 0.5;
sunLight.shadow.camera.far = 100;
sunLight.shadow.camera.left = -10;
sunLight.shadow.camera.bottom = -10;
sunLight.shadow.camera.top = 10;
sunLight.shadow.camera.right = 10;
and a sphere with the following configuration:
let sphere = new THREE.Mesh(
new THREE.SphereGeometry(10, 70, 70),
new THREE.MeshPhysicalMaterial({
map: textures.map,
roughnessMap: textures.spec,
bumpMap: textures.bump,
bumpScale: 0.25,
envMap,
envMapIntensity: 1,
clearcoat: 0.25,
reflectivity: 0.1,
})
);
The light creates a distinct reflection on the sphere (see image).
Is there a way to have a less distinct reflection?

U-shaped magnet geometry in three.js

I want to create a "U" shaped magnet in three.js. So can I use TubeGeometry for that?
So if this is the code for creating a 3D sin curve. How can I make it as "U" shaped Magnet?
var CustomSinCurve = THREE.Curve.create(
function ( scale ) { //custom curve constructor
this.scale = ( scale === undefined ) ? 1 : scale;
},
function ( t ) { //getPoint: t is between 0-1
var tx = t * 3 - 1.5;
var ty = Math.sin( 2 * Math.PI * t );
var tz = 0;
return new THREE.Vector3( tx, ty, tz ).multiplyScalar(this.scale);
}
);
var path = new CustomSinCurve( 10 );
var geometry = new THREE.TubeGeometry( path, 20, 2, 8, false );
var material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
var mesh = new THREE.Mesh( geometry, material );
scene.add( mesh );
If the shape of the magnet's profile is not critical (rectangle instead of circle), then you can use THREE.ExtrudeGeometry():
var path = new THREE.Shape(); // create a U-shape with its parts
path.moveTo(-1, 1);
path.absarc(0, 0, 1, Math.PI, Math.PI * 2);
path.lineTo(1, 1);
path.lineTo(.8, 1);
path.absarc(0, 0, .8, Math.PI * 2, Math.PI, true);
path.lineTo(-.8,1);
path.lineTo(-1, 1);
var extOpt = { // options of extrusion
curveSegments: 15,
steps: 1,
amount: .2,
bevelEnabled: false
}
var uGeom = new THREE.ExtrudeGeometry(path, extOpt); // create a geometry
uGeom.center(); // center the geometry
var average = new THREE.Vector3(); // this variable for re-use
uGeom.faces.forEach(function(face){
average.addVectors(uGeom.vertices[face.a], uGeom.vertices[face.b]).add(uGeom.vertices[face.c]).divideScalar(3); // find the average vector of a face
face.color.setHex(average.x > 0 ? 0xFF0000 : 0x0000FF); // set color of faces, depends on x-coortinate of the average vector
});
var uMat = new THREE.MeshBasicMaterial({ vertexColors: THREE.FaceColors }); // we'll use face colors
var u = new THREE.Mesh(uGeom, uMat);
scene.add(u);
jsfiddle example

Threejs PlaneBufferGeometry: color attribute does not show

When i create a PBG with:
var geometry = new THREE.PlaneBufferGeometry(gs,gs, size - 1, size - 1);
geometry.rotateX(-Math.PI / 2);
var vertices = geometry.attributes.position.array;
for (var i = 0, j = 0, l = vertices.length; i < l; i++, j += 3) {
vertices[j + 1] = data.map[0][i];
}
I dont have a color property:
Don't know if the warnings have something to do or i'm missing something. For what i can see in the code, PlaneBufferGeometry extends from BufferAttribute and should have color.
Tips?
Thanks!
Edit: Material:
var material = new THREE.MeshPhongMaterial({
color: 0xaaaaff,
vertexColors: THREE.FaceColors,
shading: THREE.FlatShading,
side: THREE.DoubleSide
});

Drawing custom shapes in Babylon.js

I have been searching all over the web for a way to draw custom 3d shapes in babylon.js. I would be grateful if somebody could provide a working example. For instance, a 3d irregular pentagon, triangle fan, or a wedge.
you can find a lot of info about parametric shapes in Babylon.js here:
http://doc.babylonjs.com/page.php?p=24847
And mainly for the ribbon here:
http://doc.babylonjs.com/page.php?p=25088
Here is a wedge using the ribbon object:
var createScene = function() {
var scene = new BABYLON.Scene(engine);
scene.clearColor = new BABYLON.Color3(0.8, 0.8, 0.8);
var camera = new BABYLON.ArcRotateCamera("Camera", 3 *Math.PI / 2, Math.PI / 2, 20, BABYLON.Vector3.Zero(), scene);
camera.attachControl(canvas, false);
// lights
var light = new BABYLON.HemisphericLight("hemi", new BABYLON.Vector3(0, 1, 0), scene);
light.groundColor = new BABYLON.Color3(0.2, 0.2, 0.5);
light.intensity = 0.6;
var light2 = new BABYLON.PointLight("light2", new BABYLON.Vector3(-20, 0, -20), scene);
light2.diffuse = BABYLON.Color3.White();
light2.specular = BABYLON.Color3.Green();
light2.intensity = 0.6;
// material
var mat = new BABYLON.StandardMaterial("mat1", scene);
mat.alpha = 1.0;
mat.diffuseColor = new BABYLON.Color3(0.5, 0.5, 1.0);
//mat.backFaceCulling = false;
mat.wireframe = true;
// tubular ribbon
path1 = [];
path2 = [];
path1.push( new BABYLON.Vector3(0, 0, 0) );
path2.push( new BABYLON.Vector3(0, 2, 0) );
path1.push( new BABYLON.Vector3(1, 0, 0) );
path2.push( new BABYLON.Vector3(1, 2, 0) );
path1.push( new BABYLON.Vector3(0, 0, 1) );
path2.push( new BABYLON.Vector3(0, 2, 1) );
var ribbon = BABYLON.Mesh.CreateRibbon("ribbon", [path1, path2], false, true, 0, scene);
ribbon.material = mat;
scene.registerBeforeRender(function(){
light2.position = camera.position;
});
return scene;};

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 :(

Resources