前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >threejs三维模型添加文字标签,及添加文字的方式介绍

threejs三维模型添加文字标签,及添加文字的方式介绍

作者头像
程序你好
发布2021-07-23 14:38:46
19K0
发布2021-07-23 14:38:46
举报
文章被收录于专栏:程序你好程序你好

上次在文章ThreeJS中三维世界坐标转换成二维屏幕坐标介绍了三维二维坐标的转换方法,今天结合一个用例具体说下用法。

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

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

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

添加立方体模型:

var cubeMaterial = new THREE.MeshStandardMaterial({color:0x00ffff});

cube = new THREE.Mesh(cubeGeometry, cubeMaterial);

cube.position.set(300,100,100);

scene.add(cube);

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

<div id="info1">这是球体</div>

<div id="info2">这是立方体</div>

#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;

}

在OnRender方法中写坐标系转换代码:

代码语言:javascript
复制
					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三维场景中添加文字有很多不同的方法,上面说的DIV+CSS的方式应该是最简单也最快速方式。

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

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

示例:

代码语言:javascript
复制
				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);

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

代码语言:javascript
复制
					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包中提供的字体都是英文字体,如果想显示中文需要加入中文字体的json文件。

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

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

代码:

代码语言:javascript
复制
        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。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-07-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 程序你好 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
图像处理
图像处理基于腾讯云深度学习等人工智能技术,提供综合性的图像优化处理服务,包括图像质量评估、图像清晰度增强、图像智能裁剪等。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档