Add text with geometry in threejs

青春壹個敷衍的年華 提交于 2020-05-16 08:06:29

问题


I want to attach text to the bottom part of the rings (where the cuts are) as you can see in the image below. You can see the code I am using to draw the rings. I want to write the radius (40m, 30m, 20m) where the cuts are and I would prefer that they are merged because I will be zooming them in and out and want them to stay connected to the rings.

// Rings
// 40m ring
const geometry40m = new THREE.RingGeometry(35, 35.6, 30, 8, 4.85, 6);
geometry40m.lookAt(this.CAMERA_POSITION);
const ringMesh40m = new THREE.Mesh(geometry40m, whiteMaterial);

ringMesh40m.updateMatrix();
// geometry40m.mergeMesh(new THREE.Mesh(textGeometry, whiteMaterial));

// 30m ring
const geometry30m = new THREE.RingGeometry(26, 26.6, 30, 8, 4.85, 6);
geometry30m.lookAt(this.CAMERA_POSITION);

geometry30m.mergeMesh(ringMesh40m); // adding 40m and 30m to one mesh

const ringMesh40_30m = new THREE.Mesh(geometry30m, whiteMaterial);
ringMesh40_30m.updateMatrix();

// 20m ring
const geometry20m = new THREE.RingGeometry(16, 16.6, 30, 8, 4.85, 6);
geometry20m.lookAt(this.CAMERA_POSITION);

geometry20m.mergeMesh(ringMesh40_30m); // adding 40m, 30m and 20m to one mesh

const ringMesh40_30_20m = new THREE.Mesh(geometry20m, whiteMaterial);
this.rings = ringMesh40_30_20m;
this.rings.layers.set(15);
this.rings.visible = true;
this.scene.add(this.rings);


回答1:


You can add Mesh objects with PlaneGeometry and Basic material textured with a CanvasTexture objects. Position them in the cuts and update the texture content with text showing the size.

If you want them to be always facing screen, you can use Sprite objects instead of Mesh




回答2:


For anyone else looking for the answer, I ended up creating text labels using this function:

createTextMesh(text, font, size, mat) {
   var shapes = font.generateShapes(text, size);

   var geometry = new THREE.ShapeBufferGeometry(shapes);

   geometry.center();
   geometry.computeBoundingBox();

   return new THREE.Mesh(geometry, mat);
}

and this is what I end up doing and it worked for me:

// Rings

// 40m ring
const geometry40m = new THREE.RingGeometry(
  RADIUS_40M,
  RADIUS_40M + 0.6,
  30,
  8,
  4.85,
  6);

// 30m ring
const geometry30m = new THREE.RingGeometry(
  RADIUS_30M,
  RADIUS_30M + 0.6,
  30,
  8,
  4.85,
  6);
geometry30m.merge(geometry40m);

// 20m ring
const geometry20m = new THREE.RingGeometry(
  RADIUS_20M,
  RADIUS_20M + 0.6,
  30,
  8,
  4.85,
  6
);
geometry20m.merge(geometry30m);

// adding 40m, 30m and 20m to one mesh
const ringMesh40_30_20m = new THREE.Mesh(geometry20m, whiteMaterial);
ringMesh40_30_20m.layers.set(16);
ringMesh40_30_20m.visible = true;
ringMesh40_30_20m.name = "rings";

this.rings = new THREE.Object3D();
this.rings.add(ringMesh40_30_20m);

// Labels

const fontJson = require("../../../assets/helvetiker_regular.typeface.json");
const font = new THREE.Font(fontJson);

let label20m = this.createTextMesh("20m", font, 0.5, whiteMaterial);
label20m.layers.set(16);
label20m.visible = true;
label20m.name = "label20m";

let label30m = this.createTextMesh("30m", font, 2.2, whiteMaterial);
label30m.layers.set(16);
label30m.visible = true;
label30m.name = "label30m";

let label40m = this.createTextMesh("40m", font, 2.5, whiteMaterial);
label40m.layers.set(16);
label40m.visible = true;
label40m.name = "label40m";

this.rings.add(label20m);
this.rings.add(label30m);
this.rings.add(label40m);

this.rings.getObjectByName("label20m").position.y = -RADIUS_20M;
this.rings.getObjectByName("label30m").position.y = -RADIUS_30M;
this.rings.getObjectByName("label40m").position.y = -RADIUS_40M;
this.rings.lookAt(this.CAMERA_POSITION);
this.scene.add(this.rings);

I got the font from the three.js official Repo



来源:https://stackoverflow.com/questions/61631545/add-text-with-geometry-in-threejs

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!