three.js 2D 文本精灵标签

Posted

技术标签:

【中文标题】three.js 2D 文本精灵标签【英文标题】:three.js 2D Text sprite labels 【发布时间】:2014-06-24 05:20:05 【问题描述】:

我是 three.js 的新手,遇到一些属于 2D 文本的问题:

我想要什么: 我想要一些标签,例如。 x、y 和 z 轴。标签应始终朝向相机。也许稍后它们应该只显示,如果它们悬停,但这是另一个主题。

我有什么问题 我找到了这个教程(这正是我想要达到的效果|http://stemkoski.github.io/Three.js/Sprite-Text-Labels.html),但它是针对使用var spriteAlignment = THREE.SpriteAlignment.topLeft; 之类的方法的three.js 的旧版本。我找到了这个解决方法 (THREE.SpriteAlignment showing up as undefined),但我不清楚如何使用新方法来满足我的需求。

我在寻找什么 也许你可以帮我命名我正在搜索的那个东西,或者想出一个简短的方法。

【问题讨论】:

看看***.com/questions/23351835/… 是否足以让您入门。如果您遇到问题,请展示您的代码的实时示例并提出具体问题。 【参考方案1】:

Text Sprites 很好,但如果你使用超过一千个,它可能会因为 GPU 而减慢一切。

有一种“更好”的方法,将 Sprite 创建为 Canvas,这是我也使用的一个函数:

    function makeTextSprite( message, parameters )
    
        if ( parameters === undefined ) parameters = ;
        var fontface = parameters.hasOwnProperty("fontface") ? parameters["fontface"] : "Arial";
        var fontsize = parameters.hasOwnProperty("fontsize") ? parameters["fontsize"] : 18;
        var borderThickness = parameters.hasOwnProperty("borderThickness") ? parameters["borderThickness"] : 4;
        var borderColor = parameters.hasOwnProperty("borderColor") ?parameters["borderColor"] :  r:0, g:0, b:0, a:1.0 ;
        var backgroundColor = parameters.hasOwnProperty("backgroundColor") ?parameters["backgroundColor"] :  r:255, g:255, b:255, a:1.0 ;
        var textColor = parameters.hasOwnProperty("textColor") ?parameters["textColor"] :  r:0, g:0, b:0, a:1.0 ;

        var canvas = document.createElement('canvas');
        var context = canvas.getContext('2d');
        context.font = "Bold " + fontsize + "px " + fontface;
        var metrics = context.measureText( message );
        var textWidth = metrics.width;

        context.fillStyle   = "rgba(" + backgroundColor.r + "," + backgroundColor.g + "," + backgroundColor.b + "," + backgroundColor.a + ")";
        context.strokeStyle = "rgba(" + borderColor.r + "," + borderColor.g + "," + borderColor.b + "," + borderColor.a + ")";

        context.lineWidth = borderThickness;
        roundRect(context, borderThickness/2, borderThickness/2, (textWidth + borderThickness) * 1.1, fontsize * 1.4 + borderThickness, 8);

        context.fillStyle = "rgba("+textColor.r+", "+textColor.g+", "+textColor.b+", 1.0)";
        context.fillText( message, borderThickness, fontsize + borderThickness);

        var texture = new THREE.Texture(canvas) 
        texture.needsUpdate = true;

        var spriteMaterial = new THREE.SpriteMaterial(  map: texture, useScreenCoordinates: false  );
        var sprite = new THREE.Sprite( spriteMaterial );
        sprite.scale.set(0.5 * fontsize, 0.25 * fontsize, 0.75 * fontsize);
        return sprite;  
    

【讨论】:

roundRect函数从何而来?您能否包含指向库或功能代码的链接?谢了! 我认为这是 Lee Stemkoski 的一个功能,看看他的网站有很多很好的例子。 函数 roundRect(ctx, x, y, w, h, r) ctx.beginPath(); ctx.moveTo(x + r, y); ctx.lineTo(x + w - r, y); ctx.quadraticCurveTo(x + w, y, x + w, y + r); ctx.lineTo(x + w, y + h - r); ctx.quadraticCurveTo(x + w, y + h, x + w - r, y + h); ctx.lineTo(x + r, y + h); ctx.quadraticCurveTo(x, y + h, x, y + h - r); ctx.lineTo(x, y + r); ctx.quadraticCurveTo(x, y, x + r, y); ctx.closePath(); ctx.fill(); ctx.stroke(); 你是如何确定sprite.scale.set(0.5 * fontsize, 0.25 * fontsize, 0.75 * fontsize);中的常量的? 这段代码帮了很多忙,但我使用的是:sprite.scale.set(0.5 * fontsize, 0.25 * fontsize, 0.75 * fontsize);,而不是:sprite.scale.set(0.002 * canvas.width, 0.0025 * canvas.height);,无论文本有多长或多短,我都能得到完美缩放的文本。【参考方案2】:

我在 NPM 上发布了一个模块,可以为您做到这一点:https://github.com/gamestdio/three-text2d

它允许您拥有带有渲染文本的Object3D,而无需手动处理画布。

示例:

var Text2D = require('three-text2d').Text2D

var text = new Text2D("Hello world!",  align: textAlign.right, font: '30px Arial', fillStyle: '#000000', antialias: true )
scene.add(text) 

【讨论】:

上面sn-p中文字的3d位置怎么设置?【参考方案3】:

您可以使用我的 SpriteText 对象。查看使用sprites_text的示例。

代码示例:

var spriteText = new THREE.SpriteText( text: 'Hello world!' );
scene.add( spriteText );

Source.

【讨论】:

以上是关于three.js 2D 文本精灵标签的主要内容,如果未能解决你的问题,请参考以下文章

将 3D 位置转换为 2d 屏幕位置 [r69!]

three.js(16)-精灵图

three.js 3d 空间中的 .svg 资产

在three.js中动态创建二维文本

Three.js/WebGL 和 2D Canvas -- 将 getImageData() 数组传递给 Three.DataTexture()

Three.js - 3D 空间中的 2D 对象(通过 Vertices)