Three.js模型标签

Three.js模型标签

在很多的实际的项目中,你可能需要给一个Three.js的模型添加标签,标签可以通过一个包含文字图形信息的HTML元素或者一个three.js的精灵模型来表示。

常见问题

  • three.js三维模型如何添加注释文字?
  • Three.js模型对象如何设置标签?
  • three.js如何用HTML元素设置显示热点
  • 如何把模型的世界坐标转化为屏幕坐标?

每个人的基础不同,虽然知识点区别不大,可能描述的时候会有很大区别。

视频讲解和源码

下面对知识点简单介绍,关于视频讲解可以关注我博客发布可的相关课程,个人WebGL/Three.js技术博客

层级模型

复杂的项目,一个three.js场景往往包含包含多个模型对象,模型对象也会有一些父对象,这样就会形成一个层级模型,从数据结构的角度来看就是树结构。
一个模型相对世界坐标系原点的位置是世界坐标,相对父对象的位置是局部坐标。

获取模型位置

你如果想给一个模型设置标签,首先需要获得模型在世界坐标系中所在的位置,如果你希望标注一个模型的某个局部位置,那就要获得该局部区域的一个顶点坐标。

  • .position属性是一个模型的局部位置,相对父对象的位置,如果一个网格模型Mesh直接属于场景Scene,没有除了Scene意外的父对象
  • .vertices如果几何体是Geometry类型,可以通过.vertices属性访问顶点,通过下标可以访问具体的顶点位置坐标。
  • .attributes.position如果几何体是BufferGeometry类型,可以通过.attributes.position属性访问顶点位置数据。
  • .getWorldPosition()实际项目中一个模型对象可以有多个父对象,这个时候想获得该模型对象的世界坐标,就不能通过.position属性,应该通过.getWorldPosition()方法实现,该方法的使用参考基类Object3D

实际项目中获得一个模型,可能是通过点击获得,或者遍历对象根据属性值找到某个或某些模型,等等这里不展开说,这不是本节课的重点,关于递归遍历模型或者鼠标点击选中某个模型可以关注课程的其它部分。

精灵模型Sprite作为标签

在使用精灵模型表示标签之前,你应该先了解精灵模型Sprite有什么特点。使用精灵模型表示一个模型对象的标签,那么精灵模型就要位于模型对象的附近。可以获得要标注模型的世界坐标,然后来设置精灵标签的位置,适当偏移一点就可以,当然也可以把精灵对象插入到模型对象的父对象中,和模型对象一样作为父对象的子对象,这样的话如果模型父对象的位置变化,精灵模型可以跟着一起变化。

标签的样式可以让美术设计好直接作为精灵的贴图就可以,如果标签不是特定的,比如用户输入文字,平台自动生成模型标签,可以通过程序自动化合成一个纹理作为精灵模型的贴图,关于如何自动合成纹理贴图这里不详细阐述。

/**
 * 创建点精灵模型
 */
// 创建精灵材质对象SpriteMaterial
var spriteMaterial = new THREE.SpriteMaterial({
  map:  new THREE.TextureLoader().load("立方体.png"), //设置精灵纹理贴图
  transparent: true,//开启透明(纹理图片png有透明信息)
});
// 创建精灵模型对象,不需要几何体geometry参数
var sprite = new THREE.Sprite(spriteMaterial);
sprite.scale.set(30, 30, 1); //精灵大小
// 把精灵模型插入到模型对象的父对象下面
group.add( sprite);
// 父对象group位置变化,网格模型及其对象的标签同样发生变化
group.position.set(10, 0, -80);
// 表示标签信息的精灵模型对象相对父对象设置一定的偏移
sprite.translateY(30);

div等html元素作为标签(世界坐标转屏幕坐标)

通过html元素表示标签相比较使用精灵来说比较麻烦,需要进行坐标变换,一个模型显示在Canvas画布上,经过了相机的视图、投影变换,如果想把一个div元素标注在一个模型附近,就需要计算模型渲染到画布上的具体位置,也就是所谓的屏幕坐标。使用html元素的好处是可以直接输入汉字,利用css来设置一下标签的样式,当然也可以直接加载美术设计的标签。

世界坐标转WebGL标准设备坐标

  • 世界坐标:世界坐标简单说就是模型在three.js三维空间中的位置,但是注意不是局部位置属性.position,你可以通过.getWorldPosition()方法获得世界坐标,每个子对象都有一个相对父对象的位置,把一个对象的所有父对象相对Scene坐标原点的位置加起来就是一个模型的世界坐标
  • 屏幕坐标:你可以理解为Canvas画布上的位置,单位是像素px,这和HTML说的像素是一样的。
//创建一个三维向量作为世界坐标
var worldVector = new THREE.Vector3();
//获取网格模型boxMesh的世界坐标,赋值给worldVector
boxMesh.getWorldPosition(worldVector);
//世界坐标转标准设备坐标,standardVector是WebGL设备坐标
var standardVector = worldVector.project(camera);

.project()是向量Vector3的方法,一个表示位置的向量Vector3把相机作为参数执行该方法可以得到经过相机变换后的坐标。一般threejs渲染器渲染的时候,会自动从相机对象读取视图和投影矩阵对模型的顶点进行变换。

WebGL标准设备坐标转屏幕坐标

Canvas全屏显示的时候复合下面的计算规则,如果不是全屏要注意修改计算规则。如果不是全屏,计算a和b的值,不能使用window.innerWidth,而应该使用canvas的具体宽高。如果canvas是局部显示相对body区域的左上角有偏移,那么div元素也要设置一定的偏移。

// 根据WebGL标准设备坐标standardVector计算div标签在浏览器页面的坐标
var a = window.innerWidth / 2;
var b = window.innerHeight / 2;
var x = Math.round(standardVector.x * a + a); //标准设备坐标转屏幕坐标
var y = Math.round(-standardVector.y * b + b); //标准设备坐标转屏幕坐标
/**
 * 设置标签元素的位置
 */
div.style.left = x + 'px';
//这里的130px主要是为了标签和模型有一定偏移,当然也可以不设置,两者叠加在一起
div.style.top = y - 130 + 'px';
screen.png
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 200,527评论 5 470
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,314评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 147,535评论 0 332
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,006评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,961评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,220评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,664评论 3 392
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,351评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,481评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,397评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,443评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,123评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,713评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,801评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,010评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,494评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,075评论 2 341

推荐阅读更多精彩内容

  • 第一部分 HTML&CSS整理答案 1. 什么是HTML5? 答:HTML5是最新的HTML标准。 注意:讲述HT...
    kismetajun阅读 27,381评论 1 45
  • Threejs中文文档 郭隆邦技术博客 2018-09-21 20:40:17 关注 Three.js中文文档 今...
    情人波阅读 13,782评论 0 7
  • HTML标签解释大全 一、HTML标记 标签:!DOCTYPE 说明:指定了 HTML 文档遵循的文档类型定义(D...
    米塔塔阅读 3,219评论 1 41
  • 目前为止,来北京有3年了,陆陆续续住的地方也换了4、5个了,总结了下经验教训,希望能对大家有所帮助 1、明确自身条...
    晓虫阅读 203评论 0 2
  • 一日为蓝,终身向前
    给自己画眉阅读 163评论 0 0