Removing edges from WireframeGeometry in three.js - 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.

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

Positioning Objects at the same Elevation

I have an issue with the position of cubes in my application. When I set them all with the same size they are rendered properly on the same Y position as I defined:
Example:
geometry = new THREE.BoxGeometry(50, 50, 50);
material = new THREE.MeshBasicMaterial({ color: 0xff0000 })
mesh = new THREE.Mesh(geometry, material);
mesh.position.set(100, 0, 400); // I always set y as 0 because I want the cubes to be on the same level like buildings in a city
And I do the same for the next cubes, only changing the X and Z positions.
However, when I create cubes with different sizes, which is my objective, as follows,
geometry = new THREE.BoxGeometry(50, 100, 50);
they appear on a different level in the final visualization on the browser, as shows the image:
https://cloud.githubusercontent.com/assets/3678443/8651664/35574c18-2972-11e5-8c75-2612733ea595.png
Any ideas on how to solve this problem? What am I doing wrong?
BoxGeometry is centered on the origin. There are two solutions to translating the box so it sits on the XZ-plane.
Option 1. Translate the geometry so the bottom face of the box passes through the origin. You do that by translating the geometry up by half its height.
geometry = new THREE.BoxGeometry( 50, 50, 50 );
geometry.translate( 0, 50 / 2, 0 );
mesh = new THREE.Mesh( geometry, material );
mesh.position.set( 100, 0, 400 );
Option 2. Translate the mesh by setting its position.
geometry = new THREE.BoxGeometry( 50, 50, 50 );
mesh = new THREE.Mesh( geometry, material );
mesh.position.set( 100, 50 / 2, 400 );
The first option is likely preferable for your use case.
three.js r.92
The Position of the Objects is correct, they are placed where their centerĀ“s are. So your cube with 100 height in geometry extends 50 to the top and 50 to the bottom, its centroid is right in its "middle" at 0.
You could set the y positions of your Cubes to y + cube.geometry.parameters.height / 2 so every cube is aligned at one level (variable y).

Vertex Colors in THREE.Line

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

three.js: Using BufferGeometry with circles (or other shapes)

would it be possible to use bufferedgeometry filled with circles or other shapes? by circles i mean filled circles
i have tried drawing a circle via a series of "Line"s, but of course it wans't a filled circle, i have also tried using a ParticleCloud with pngs that looked like circles, but then the performance wouldn't be as good as native meshed circle i guess.
the closest i got to is when i drew a circle via a series of multiple "Mesh" objects but it is very cumbersome.
does BufferGeometry even support such thing?
In three.js there is CircleBufferGeometry
var geometry = new THREE.CircleBufferGeometry( 5, 32 );
var material = new THREE.MeshBasicMaterial( { color: 0xffff00 } );
var circle = new THREE.Mesh( geometry, material );
scene.add( circle );

How do I use a Canvas texture on a 3D polygon face that is not a rectangle

I have a mesh with plane geometry that I texture with a 2D canvas element. This is working perfectly.
var landTexture = new THREE.Texture(land.canvas); // animated canvas element
var material = new THREE.MeshLambertMaterial({map: landTexture});
var plane = new THREE.Mesh( new THREE.PlaneGeometry( this.land_width, this.land_height ), material );
landTexture.needsUpdate = true;
landObject.add(plane);
The 2D canvas has an animated pattern which I want to use as a texture on a pentagon instead of a plane. How do I go about texturing more complex polygons, e.g. a pentagon, with a 2D canvas texture?
Edit: how I generate the pentagon
var pentagon = new THREE.Mesh( new THREE.CircleGeometry(this.land_width, 5), material );
Screenshot of the animated texture on PlaneGeometry and the same texture on a CircleGeometry with 5 sides. Notice the "stretched" canvas texture on the pentagon, which is not what I want. It should fit proportionally.
I think that the UVs are already set so that code such as:
var grid = new THREE.ImageUtils.loadTexture( 'images/uvgrid01.jpg' );
var pentagon = new THREE.Mesh( new THREE.CircleGeometry(50, 5), new THREE.MeshBasicMaterial({map:grid}) );
when the grid is the image:
will produce an image like:
Is that what you're looking for? Then all that is left is to update the texture repeatedly, and each time this is done, set the flag to update the material. I can go into more detail, but I would need to know how the canvas is being animated.

Resources