将标签放在场景Three.JS中的每个节点(Three.Point)上

时间:2017-07-31 22:23:23

标签: three.js

我是three.js的新手,并修改了一些现有的代码。

现有代码使用“THREE.BufferGeometry”+“THREE.Points”呈现图形

var geometryPc = new THREE.BufferGeometry();
var materialPc = new THREE.ShaderMaterial({....});
this.mesh = new THREE.Points(geometryPc, materialPc);

我试图在与节点一起移动的每个节点上放置标签文本。

我试过了:

我尝试为每个节点创建“THREE.Sprite”,然后分配相对于该节点的位置。

let texture = new THREE.Texture(canvas);
let spriteMaterial = new THREE.SpriteMaterial({map: texture, useScreenCoordinates: false});
let sprite = new THREE.Sprite(spriteMaterial);

这似乎有效,但当节点数量相对较高时,UI变得太重了。

我更喜欢使用“BufferGeometry”来创建文本。但是找不到办法做到这一点。

有没有更好的方法将文字放在节点上?

1 个答案:

答案 0 :(得分:2)

你的精灵方法,到目前为止最明显,不幸的是还不够。如果我理解正确的话,每个精灵都会创建自己的纹理,因此每个精灵都会产生一个单独的绘制调用。这种方法不具备可扩展性。

我这样做的方法是制作一个能够渲染图像不同部分的着色器,然后制作一个包含字母的图像(采用等宽字体)。然后,对于几何中的每个点(应该渲染标签的位置),我为每个呈现的字母传递一组参数(着色器属性):

    positionX: this.position.x, //position of entire label
    positionY: this.position.y,
    positionZ: this.position.z,
    colorR: this.color.r,
    colorG: this.color.g,
    colorB: this.color.b,
    colorA: this.visible ? (this.finalAlpha) : 0,
    scale: this.camera.zoom, //scale must depend on camera zoom
    spriteNumber: this.getTextPosition(lines[i][j]), //see below ;p
    offset: j + i * 32768, //this is for positioning one particular letter, 
                           //x and y merged together because I ran out of parameters
    size: this.size 

我和j是" x"和" y"标签中的字母位置,着色器自行抵消;其他参数应该或多或少明显:)

ParticleLabel.prototype.getTextPosition = function(symbol){
    switch(symbol){
    case '0': return 1;
    case '1': return 2;
    case '2': return 3;
    (...)
    case 'A': return 20;
    case 'B': return 21;
    case 'C': return 22;
    (...)

我无法显示整个代码,因为我是为商业解决方案制作的,但我会在codepen上做一个例子,或者稍后再展示一个有效的解决方案。