threejs render text on or next to object - d3.js

How can I put a text next or in front of it or on its surface with three.js?
If I plot a object like a box, I'd like to give this object a visible name (so similar to tooltip, but always staying visible). Would be great if text size is adjusting to distance like object size.
const geometry = new THREE.BoxGeometry( 1, 1, 1 );
const material = new THREE.MeshBasicMaterial( {color: 0x00ff00} );
const cube = new THREE.Mesh( geometry, material );
scene.add( cube );
I'm using three.js with react-force-graph to render a diagram. Objects within it are rendered with three.js
https://threejs.org/docs/#api/en/geometries/BoxGeometry.parameters

Two ways to draw text with three.js. First, create a div element, set its position (In your case, you need to write code to calculate the position relative to the canvas according to the position of camera and 3d object). Second, create a text texture.

Related

threejs - creating 3d perspective for a line

I'm working on an app where I visualize ATV trails in a 3d perspective (NAIP imagery draped over elevation data). I am using three.js for the rendering engine.
In the above image, the white line you see is just a THREE.Line instance, where I convert a trails gps coordinates into threejs coordinates. I'd like to add more of 3d perspective to this line. I tried implementing a THREE.TubeGeometry where the path was a THREE.CatmullRomCurve3 using the same Vector3 points as how I built the line you see in the image above. That did not produce a desirable result...
From the many, many THREE examples I have looked at, I really think an extruded geometry would achieve the look I am after... But I cant for the life of me figure out how to extrude a geometry for the line. Any suggestions/thoughts?
UPDATE 1:
Here is my desired look (same trail - no imagery). This image was produced in QGIS using the Q2Threejs plugin
UPDATE 2: Here is a code of how I have attempted to create a tubegeometry. Maybe I am messing something up in there...
// trailVectors are an array of Vector3 - same as ones used to create line
var trailCurve = new THREE.CatmullRomCurve3(trailVectors);
var tubeGeometry = new THREE.TubeGeometry(trailCurve,80,1,15,false);
var material = new THREE.MeshBasicMaterial({color:0x00ff00});
var tubeMesh = new THREE.Mesh(tubeGeometry,material);
var wireframeMaterial = new THREE.LineBasicMaterial({color:0xffffff,lineWidth:2});
var wireframe = new THREE.Mesh(tubeGeometry,wireframeMaterial);
tubeMesh.add(wireframe);
scene.add(tubeMesh);
UPDATE 3
THREE.TubeGeometry(trailCurve,80,4,2,false) per mzartman request
I think that you should be able to achieve what you want with a TubeGeometry. I think the big thing is that your example (from the picture shown) has more than 2 radius segments. That gives it the tubular shape and makes it look sort of like a blob. If you set the radial segment count to 2 (as it's shown below) then I think it would look a lot better.
tubeGeometry = new THREE.TubeBufferGeometry(
[YOUR_PATH_HERE],
params.extrusionSegments, // <--- Edit this for higher resolution on the spline
3, // <--- This defines the height
2, // <--- This 2 keeps 2D (i.e. not a tube!!!!)
true );
var mesh = new THREE.Mesh( geometry, material );
var wireframe = new THREE.Mesh( geometry, wireframeMaterial );
mesh.add( wireframe );
scene.add( mesh );
Update:
I think that you might do better with a material that shows some shadow like the MeshPhong. Also, to do the wireframe you want to add it as an option in the material initialization. Give it a show with the following:
var tubeGeometry = new THREE.TubeGeometry(curve,80,1,2,false);
var material = new THREE.MeshPhongMaterial({color:0x00ff00, wireframe: true});
var tubeMesh = new THREE.Mesh(tubeGeometry,material);
scene.add(tubeMesh);

Three JS randomPointsInGeometry always gives box shape

Im trying to make a particle system adapt to a certain geometric shape, I am using THREE.GeometryUtils.randomPointsInGeometry and can and array from this that I can then position particles however regardless of the geometry I use (primitive or dae) the particles fill the space of the geometry bounding (I presume) and always fill a box shape.
The key lines
var object = new THREE.Mesh( new THREE.OctahedronGeometry( 50, 2 ), new
THREE.MeshBasicMaterial( {color: 0x00ff00} ) );
var positionsX =
THREE.GeometryUtils.randomPointsInGeometry(object.geometry, 20000);
Full running code here:
https://jsfiddle.net/joe_shields/5sbcfzqt/5/
Any Ideas what I need to change to ensure that the particles honour the shape fo the original geometry?

How to scale/resize Mesh Outline?

In my current project, I need a way to outline a mesh.This color outline will represent the object's current state, relevant for me.
The problem is that it is a custom mesh, loaded using JSONLoader.
I've tried different approaches, following (mainly) these 2 examples: https://stemkoski.github.io/Three.js/Outline.html and
THREEx.geometricglow. In both cases, I scale the mesh outline to a bit bigger than the original. My main problem is that scaling equally in all axis will not cover my object the way I intended to.
Here is the code I'm using:
var outlineMaterial2 = new THREE.MeshBasicMaterial( { color: 0x00ff00, side: THREE.BackSide, transparent: true, opacity:0.5 } );
var outlineMesh2 = new THREE.Mesh( object.geometry, outlineMaterial2 );
outlineMesh2.position.copy(object.position);
outlineMesh2.scale.copy(object.scale);
outlineMesh2.scale.multiplyScalar(1.1)
scene.add( outlineMesh2 );
`
With a simple cube mesh, the outline will be good.
But with my custom mesh, the scale will not fit the shape correctly.
Here is a image demonstrating: http://s13.postimg.org/syujtd75z/print1.png
Also, using Stemkoski approach, the outlining mesh will also show in front of the object, not just outline (as seen in the above picture).
My question is: How should I resize the mesh? For what I know, it might have something to do with face normals.
Thanks for your time.

Combine THREE.MeshFaceMaterial and THREE.BackSide?

Using three.js v56:
I have an array of textures called materialArray, then I create
var cubeMaterial = new THREE.MeshFaceMaterial( materialArray );
However, I would like this texture to be reversed; for a "normal" material called simpleMaterial, one would enter:
simpleMaterial.side = THREE.BackSide;
Alas, this has no effect in this case; the material is still displayed on the "front" side.
So, how can the texture be set to the backside when working with an array of textures as in MeshFaceMaterial?
Thanks in advance!
materialArray needs to be an array of materials, not an array of textures.
You must set the side property to THREE.BackSide for each material in the material array that you want flipped.
three.js r.56

three.js share a geometry for lines and particles

I would like to use one geometry object for some fancy particle animation and display lines between those particles.
geometry = new THREE.Geometry();
particles = new THREE.ParticleSystem(geometry, particleMaterial);
line = new THREE.Line(geometry, lineMaterial, THREE.LinePieces);
Somehow the Line Object is not rendered in the scene, but the particles show up.
http://jsfiddle.net/Pk85y/1/
With WebGLRenderer you can't share geometry in some specific situations. Best option is to do geometry.clone().
Here's the jsfiddle fixed: http://jsfiddle.net/Pk85y/3/

Resources