Inconsistent alpha channel in three.js - three.js

I'm building an educational tool using planes, extruded splines, and cylinder geometries. Planes have a texture map and the rest are either basic or Lambert materials.
Texture map on planes in the only map and it does have an alpha
channel.
Texture map has been tested as .GIF and .PNG
All objects have "transparent: true"
renderer = new THREE.WebGLRenderer( {antialias:true} );
NOTE: this is the exact same problem listed at the following link. It has not been solved and my Rep isn't high enough to comment.
in three.js, alpha channel works inconsistently
As mmaclaurin noted, it could be a change based in draw order and camera location. I am using THREE.TrackballControls and limiting camera movement to two axes.
Adding or removing the BasicMaterial for wireframe does not change the issue.
Thank you for your time reading this and any help you can offer!
Example of plane object:
var T4map = new THREE.ImageUtils.loadTexture( 'medium_T4.png' );
var T4Material = new THREE.MeshBasicMaterial( { opacity: .96, transparent:true, map: T4map } );
var T4Geometry = new THREE.PlaneGeometry(810, 699, 10, 10);
var T4 = new THREE.Mesh(T4Geometry, T4Material);
T4.position.y = -CNspacing;
T4.doubleSided = true;
scene.add(T4);
Example of extruded spline geometry where problem is most noticeable:
var mesh = THREE.SceneUtils.createMultiMaterialObject( geometry, [
new THREE.MeshLambertMaterial( { color: 0xaaff00, opacity: 0.5, transparent: true } ),
mesh.position.set( x, y, z );
mesh.scale.set( s, s, s );
parent.add( mesh );

Try to play around with depthTest. Usually this would help:
new THREE.MeshBasicMaterial( { side:THREE.BackSide,map:texture,transparency:true, opacity:0.9, depthWrite: false, depthTest: false });
There are many other questions related to your subject, for ex.: transparent bug

Was just going to comment but its too long:
Objects that are marked with transparent = true, are painters sorted based on their centroid, and drawn back to front so that the transparency layers mostly correctly. Make sure your mesh.geometries have proper computeBoundingBox() and computeBoundingSphere() applied to them before adding them... if that doesn't fix your problem, then try using material.alphaTest = 0.5 on your materials.. this works well for things that are mostly on/off alpha.. like masks... but if you have smooth gradations of transparency from 0 to 1 in your textures, you may see fringes where the alpha test threshholding happens.

Related

three.js make a cutting plane visible

In this demo:
https://threejs.org/examples/?q=clipping#webgl_clipping_advanced
if you enable the "visualize" option, you can see the 3d pyramid "cutting" the inside object.
Here:
https://threejs.org/examples/?q=clipping#webgl_clipping
there is a simple 2d plane cutting the object, but there is no such option to "see" the plane. I just started learning threejs and I am not too familiar with any 3d engine (other than fully understanding the math behind it), so I tried some basic stuff, e.g.:
localPlane.visible = true
But of course it didn't work. Any 'simple' way to make the second demo display the cutting plane?
Thank you
Here's some code to add the plane in the position you want:
const planeGeometry = new THREE.PlaneGeometry( 1.5, 1.5 );
const planeMaterial = new THREE.MeshBasicMaterial( {color: 0xffff00, side: THREE.DoubleSide} );
const plane = new THREE.Mesh( planeGeometry, planeMaterial );
plane.position.copy(localPlane.normal);
plane.position.multiplyScalar(-localPlane.constant);
plane.quaternion.setFromUnitVectors(new THREE.Vector3(0, 0, 1), localPlane.normal);
plane.material.opacity = 0.5;
plane.material.transparent = true;
scene.add( plane );
And here's what that looks like...
However, depending on what you are implementing, you may find it easier to create a Plane Mesh in the position you want, and then derive the clipping plane THREE.Plane from that.
If you want to be able to move the clipping plane around, the reasoning involved in moving a Plane Mesh Object3D is probably more straightforward than reasoning about moving a THREE.Plane.
(update)
Another alternative approach I've come across: you could simply use the built in THREE.PlaneHelper, which can be used to visualize any THREE.Plane.
https://threejs.org/docs/#api/en/helpers/PlaneHelper
The sample code offered on that page is this:
const plane = new THREE.Plane( new THREE.Vector3( 1, 1, 0.2 ), 3 );
const helper = new THREE.PlaneHelper( plane, 1, 0xffff00 );
scene.add( helper );

How to draw open end curve shapes in Threejs

I am drawing curves/polygons by using ExtrudeBufferGeometry.
Usually it always has closed ends.
For example:
My target is to draw similar shapes but open ended like
Note that my target is not "LINES" or "Planes". It must have extrude and I just want continuous points keep combining with angle (angle can be any floating point value in radian)
Your solution lies in the ExtrudeGeometry documentation, where it states:
When creating a Mesh with this geometry, if you'd like to have a separate material used for its face and its extruded sides, you can use an array of materials. The first material will be applied to the face; the second material will be applied to the sides.
So when generating the mesh, just pass 2 materials, the first one with visible: false so it doesn't get rendered.
const geometry = new THREE.ExtrudeGeometry( shape, extrudeSettings );
const materialFace = new THREE.MeshBasicMaterial( { visible: false } );
const materialSide = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
const mesh = new THREE.Mesh( geometry, [materialFace, materialSide] ) ;

THREEJS After using the subdivision modifier on a sphere the shape is no longer solid, how can I make it back into a solid object?

I am creating a cylinder and then using the subdivision modifier to round the edges. After I apply this the shape is no longer solid. Could anyone point me in the right direction for how to make it a solid color again. I tried merging the vertices but that didn't seem to do anything. Thanks!
var geometry = new THREE.CylinderGeometry(0.4, 0.4, .5, 100);
var material = new THREE.MeshLambertMaterial( {color: 0xeef007, shading: THREE.SmoothShading} );
var modifier = new THREE.SubdivisionModifier( .5 );
geometry.mergeVertices();
modifier.modify( geometry );
var cyl = new THREE.Mesh( geometry, material );
minifig.add( cyl );
screenshot
I'm assuming by "solid" you mean not flat-shaded. Recompute the normals:
modifier.modify( geometry );
geometry.computeFaceNormals();
geometry.computeVertexNormals();

Self-transparency issue in CylinderGeometry of THREE.js

I tried to draw a cylinder with MeshLambertMaterial in THREE.js, and rotate it with TrackballControl.js, but found half of the cylinder is not transparent. When rotate to some angle, the opaque half will shade the transparent half, which looks like
The essential code is
c = new THREE.CylinderGeometry( 5, 5, 20, 25 );
m = new THREE.MeshLambertMaterial( {
color:0xaaaaaa,
opacity: 0.6,
transparent: true,
side: THREE.DoubleSide
} );
scene.add( new THREE.Mesh( c, m ) );
I googled similar issue, and some people says that it's the nature of OpenGL and graphic card. I just want to confirm that is there no way to fix this problem?
Thank you!

Unexpected mesh results from ThreeCSG boolean operation

I am creating a scene & have used a boolean function to cut out holes in my wall. However the lighting reveals that the resultant shapes have messed up faces. I want the surface to look like one solid piece, rather than fragmented and displaying lighting backwards. Does anyone know what could be going wrong with my geometry?
The code that booleans objects is as follows:
//boolean subtract two shapes, convert meshes to bsps, subtract, then convert back to mesh
var booleanSubtract = function (Mesh1, Mesh2, material) {
//Mesh1 conversion
var mesh1BSP = new ThreeBSP( Mesh1 );
//Mesh2 conversion
var mesh2BSP = new ThreeBSP( Mesh2 );
var subtract_bsp = mesh1BSP.subtract( mesh2BSP );
var result = subtract_bsp.toMesh( material );
result.geometry.computeVertexNormals();
return result;
};
I have two lights in the scene:
var light = new THREE.DirectionalLight( 0xffffff, 0.75 );
light.position.set( 0, 0, 1 );
scene.add( light );
//create a point light
var pointLight = new THREE.PointLight(0xFFFFFF);
// set its position
pointLight.position.x = 10;
pointLight.position.y = 50;
pointLight.position.z = 130;
// add to the scene
scene.add(pointLight);
EDIT: Using WestLangley's suggestion, I was able to partially fix the wall rendering. And by using material.wireframe=true; I can see that after the boolean operation my wall faces are not merged. Is there a way to merge them?
Your problems are due to two issues.
First, you should be using FlatShading.
Second, as explained in this stackoverflow post, MeshLambert material only calculates the lighting at each vertex, and interpolates the color across each face. MeshPhongMaterial calculates the color at each texel.
You need to use MeshPhongMaterial to avoid the lighting artifacts you are seeing.
three.js r.68

Resources