Vertex Colors in THREE.Line - three.js

I'm trying to draw a line in Three.js with different colors for different vertices, using THREE.Line and THREE.LineBasicMaterial, with vertexColors set to THREE.VertexColors. I would prefer that there is no interpolation between the colors of adjacent vertices (such that the color just changes discontinuously at the halfway point between two vertices).
I tried setting shading: THREE.FlatShading on the material, but I realize now that that's not an option for LineBasicMaterial: http://jsfiddle.net/214huf0a/
Is there a built-in (or easy) way to prevent smoothing of color between points on a line in Three.js, or do I need to write my own shader?

You can create a line in three.js having one color on each segment by using the THREE.LineSegments and setting vertexColors = THREE.VertexColors;
for ( var i = 0; i < geometry.vertices.length; i+=2 ) {
geometry.colors[ i ] = new THREE.Color( Math.random(), Math.random(), Math.random() );
geometry.colors[ i + 1 ] = geometry.colors[ i ];
}
var material = new THREE.LineBasicMaterial( {
color: 0xffffff,
vertexColors: THREE.VertexColors
} );
var line = new THREE.LineSegments( geometry, material );
three.js r.85

Related

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] ) ;

Removing edges from WireframeGeometry in three.js

I am experimenting with THREE.js and am trying to implement a WireframeGeometry for a plane and remove the diagonal lines so that it looks like a grid of squares instead of a grid of squares with diagonal lines running through them.
Is it possible ot remove individual lines from a wireframe geometry that comes with THREE.js?
let matLine, wireframe
let geo = new THREE.PlaneGeometry( 80, 80, 80, 80 )
const geometry = new WireframeGeometry2( geo )
matLine = new LineMaterial( {
color: 0x4080ff,
linewidth: 6, // in pixels
//resolution: // to be set by renderer, eventually
dashed: false
} )
wireframe = new Wireframe( geometry, matLine )
wireframe.computeLineDistances()
wireframe.scale.set( 1, 1, 1 )
wireframe.rotation.x = Math.PI / 2
scene.add( wireframe )
Three.js faces are triangles and WireframeGeometry draws lines on the edges of faces. It's not possible to make a grid of squares with WireframeGeometry.
If you only need the grid for a Plane, you could use GridHelper:
https://threejs.org/docs/index.html?q=grid#api/en/helpers/GridHelper
But it works for only a plane and not other geometry.

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();

Merge two planes with texture into one mesh

I want to merge two meshes in threejs. I want to create a geometry of two planes that are intersecting each other perpendicular. Both of the planes must have the same texture.
I've tried the following.
Currently this error occurs: THREE.Geometry.merge(): geometry not an instance of THREE.Geometry.
var texture = THREE.ImageUtils.loadTexture('/img/foo.png');
var material = new THREE.MeshPhongMaterial( { map: texture, side: THREE.DoubleSide, transparent: true });
var m_plane_1 = new THREE.PlaneGeometry( 128, 128);
var m_plane_2 = new THREE.PlaneGeometry(128, 128);
var plane_1 = new THREE.Mesh(m_plane_1, material);
var plane_2 = new THREE.Mesh(m_plane_2, material);
plane_2.rotation.y = Math.PI / 2;
var combined = new THREE.Geometry();
combined.merge(plane_1); // does not work
//combined.merge(plane_1.geometry, plane_1.matrix); // this does not work
//combined.merge(m_plane_1.geometry, m_plane_1.matrix); // this does not work
scene.add(combined);
I've tried to read the source code for merge() but could not come to any conclusion. I've read stackoverflow threads but their approach does not work for me.
How can I solve this?
You want to get the intersection of the geometries. Then you can apply whatever texture you want to that new geometry.
To get the intersection, you should use Chandler Prall's Constructive Solid Geometry code: http://evanw.github.io/csg.js/
There are several ways to merge two geometries, but probably the simplest way to achieve what you want is to use the following pattern:
var geometry = new THREE.PlaneGeometry( 128, 128 );
var geometry2 = new THREE.PlaneGeometry( 128, 128 );
geometry2.applyMatrix( new THREE.Matrix4().makeRotationY( Math.PI / 2 ) );
geometry.merge( geometry2 );
three.js r.69
Try this:
plane_1.updateMatrix();
//Now the function merge
combined.merge(plane_1.geometry, plane_1.matrix);
//combined.merge(plane_1); // does not work
//combined.merge(plane_1.geometry, plane_1.matrix); // this does not work
//combined.merge(m_plane_1.geometry, m_plane_1.matrix); // this does not work

Inconsistent alpha channel in 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.

Resources