首页 > 建站教程 > WebGL教程 Threejs教程 >  threejs三维模型添加文字标签正文

threejs三维模型添加文字标签

在三维模型场景展示中,经常会需要对各个模型加上文字标签,而无论三维场景如果旋转变换一般文字标签总是需要面向摄像机方向,这时候代表深度的z坐标失去作用,只需用到x,y坐标。这时候需要把三维坐标转换为基于屏幕上的二维坐标。


三维模型上加文字标签最常用的方法应该就是(DOM + CSS)基于传统html5的文字实现,用于添加描述性叠加文字的方法。具体实现是声明一个绝对定位的DIV,并且保证z-index够大,保证能够显示在3D场景之上。然后计算三维坐标对应的二维坐标,根据二维坐标去设置DIV的left和top属性,让DIV在需要的位置进行展示。这种方式实现简单,DIV可方便使用页面CSS效果进行UI设置。


在三维场景上增加一个立方体,在球体和立方体上分别加上个文字标签。


添加球体模型:

const sphereGeometry = new THREE.SphereBufferGeometry(50)
const sphereMaterial = new THREE.MeshStandardMaterial({
    color: 0x00ff00
})
const sphere = new THREE.Mesh(sphereGeometry, sphereMaterial)
scene.add(sphere)


添加立方体模型:

const cubeGeometry = new THREE.BoxBufferGeometry(100, 100, 100)
const cubeMaterial = new THREE.MeshStandardMaterial({
    color: 0x00ffffff
})
const cube = new THREE.Mesh(cubeGeometry, cubeMaterial)
cube.position.set(300, 100, 100)
scene.add(cube)


页面上添加两个div及css样式:

这是球体这是立方体


#info1 {
    position: absolute;
    top: 0;
    width: 100px;
    height: 50px;
    text-align: center;
    z-index: 100;
    display:block;
    padding: 10px;
    background: rgba(255, 255, 255, 0.8);
    line-height: 1;
    border-radius: 5px;
}
#info2 {
    position: absolute;
    top: 0;
    width: 100px;
    height: 50px;
    text-align: center;
    z-index: 100;
    display:block;
    padding: 10px;
    background: rgba(255, 255, 255, 0.8);
    line-height: 1;
    border-radius: 5px;
}


添加坐标系转换代码:

var halfWidth=window.innerWidth/2;
var halfHeight=window.innerHeight/2;
var vectSphere = new THREE.Vector3(sphere.position.x,sphere.position.y,sphere.position.z);
var posiSphere =vectSphere.project(camera);;
$("#info1").css({
left:posiSphere.x*halfWidth+halfWidth,
top:-posiSphere.y*halfHeight+halfHeight,
});
var vectCube = new THREE.Vector3(cube.position.x,cube.position.y,cube.position.z);
var posiCube =vectCube.project(camera);
$("#info2").css({
left:posiCube.x*halfWidth+halfWidth,
top:-posiCube.y*halfHeight+halfHeight,
});


这样无论我怎么旋转缩放或移动三维模型,文本DIV标签都能显示在合适的位置。

threejs


threejs


在threejs三维场景中添加文字有很多不同的方法,上面说的DIV+CSS的方式应该是最简单也最快速方式。


如果希望在三维模型中绘制文本,可以把文字图片用作Texture(纹理),绘制在模型表面。


另一种常用的方式是使用three.js自带的文字几何体来添加3d或2d的文字,这种方法可以创建能够由程序改变的、动态的3D文字,可以创建一个其几何体为THREE.TextGeometry的实例的网格。需要把字体文件添加进来,在示例font目录下有json格式的几种字体。


示例:

var loader = new THREE.FontLoader();
loader.load( 'fonts/SimHei_Regular.json', function ( font ) {
var geometry = new THREE.TextGeometry( 'Hello three.js!测试', {
font: font,
size: 50,
height: 1,
curveSegments: 12,
bevelEnabled: true,
bevelThickness: 10,
bevelSize: 8,
bevelSegments: 5
});
var fontMaterial = new THREE.MeshLambertMaterial({
color: 0x808080
});
var fontModel = new THREE.Mesh(geometry,fontMaterial);
scene.add(fontModel);


threejs


接着我们在添加一个2d文字

var font2dMaterial = new THREE.MeshLambertMaterial({
color: 0x912CEE,
side: THREE.DoubleSide
});
var shapes = font.generateShapes("2d文字测试", 100, 1);
var font2dGeometry = new THREE.ShapeGeometry(shapes);
font2dGeometry.computeBoundingBox();
var font2d = new THREE.Mesh(font2dGeometry, font2dMaterial);
font2d.position.x = -0.5 * (font2dGeometry.boundingBox.max.x - font2dGeometry.boundingBox.min.x);
font2d.position.z += 1;
scene.add(font2d);


threejs


需要注意一点,在threejs包中提供的字体都是英文字体,如果想显示中文需要加入中文字体的json文件。


可以通过Facetype.js把中文字体文件转成json格式。


还有另一种更简单地添加文字的方式是使用精灵对象添加文字,不需要引入什么字体,使用Cavas直接绘制文字,因为精灵对象总是面向摄像头的,处理起来也方便。


代码:

let canvas = document.createElement("canvas");
canvas.width =400;
canvas.height = 100;
let ctx = canvas.getContext("2d");
ctx.fillStyle = "#ffff00";
ctx.font = "Bold 100px 宋体";
ctx.lineWidth = 4;
ctx.fillText("精灵中文字体",4,104);
let texture = new THREE.Texture(canvas);
texture.needsUpdate = true;
let material = new THREE.SpriteMaterial({map:texture});
let text = new THREE.Sprite(material);
text.scale.set(0.5 * 100, 0.25 * 100, 0.75 * 100);
text.position.set(0,0,50);
scene.add(text)


最后一种添加文字的方式是使用BMFonts (位图字体) ,可以将字形批处理为单个BufferGeometry。位图字体渲染支持自动换行、字母间距、字句调整等很多特性,有兴趣的朋友可以去Github看一下这个开源项目three-bmfont-text。


上一篇: three.js着色器语法glsl的常见内置函数
下一篇: threejs创建阴影
推荐教程/recommond
最新教程/new
相关教程/relation

深圳SEO优化公司大鹏网站改版龙岗网站搭建福永SEO按天计费坑梓网站建设设计南联SEO按天计费福永网站开发塘坑网络广告推广南联seo网站推广观澜阿里店铺托管民治如何制作网站大运网络推广横岗营销型网站建设沙井建网站平湖网站定制东莞关键词按天计费松岗百搜标王观澜网站开发深圳网站推广方案南澳网站优化按天计费木棉湾网站设计模板南澳百度网站优化排名深圳百搜标王布吉百搜标王观澜SEO按天计费永湖关键词排名石岩网站设计横岗如何制作网站同乐网站搜索优化坂田百度标王石岩seo网站优化歼20紧急升空逼退外机英媒称团队夜以继日筹划王妃复出草木蔓发 春山在望成都发生巨响 当地回应60岁老人炒菠菜未焯水致肾病恶化男子涉嫌走私被判11年却一天牢没坐劳斯莱斯右转逼停直行车网传落水者说“没让你救”系谣言广东通报13岁男孩性侵女童不予立案贵州小伙回应在美国卖三蹦子火了淀粉肠小王子日销售额涨超10倍有个姐真把千机伞做出来了近3万元金手镯仅含足金十克呼北高速交通事故已致14人死亡杨洋拄拐现身医院国产伟哥去年销售近13亿男子给前妻转账 现任妻子起诉要回新基金只募集到26元还是员工自购男孩疑遭霸凌 家长讨说法被踢出群充个话费竟沦为间接洗钱工具新的一天从800个哈欠开始单亲妈妈陷入热恋 14岁儿子报警#春分立蛋大挑战#中国投资客涌入日本东京买房两大学生合买彩票中奖一人不认账新加坡主帅:唯一目标击败中国队月嫂回应掌掴婴儿是在赶虫子19岁小伙救下5人后溺亡 多方发声清明节放假3天调休1天张家界的山上“长”满了韩国人?开封王婆为何火了主播靠辱骂母亲走红被批捕封号代拍被何赛飞拿着魔杖追着打阿根廷将发行1万与2万面值的纸币库克现身上海为江西彩礼“减负”的“试婚人”因自嘲式简历走红的教授更新简介殡仪馆花卉高于市场价3倍还重复用网友称在豆瓣酱里吃出老鼠头315晚会后胖东来又人满为患了网友建议重庆地铁不准乘客携带菜筐特朗普谈“凯特王妃P图照”罗斯否认插足凯特王妃婚姻青海通报栏杆断裂小学生跌落住进ICU恒大被罚41.75亿到底怎么缴湖南一县政协主席疑涉刑案被控制茶百道就改标签日期致歉王树国3次鞠躬告别西交大师生张立群任西安交通大学校长杨倩无缘巴黎奥运

深圳SEO优化公司 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化