Three.js模型標(biāo)簽

Three.js模型標(biāo)簽

在很多的實(shí)際的項(xiàng)目中,你可能需要給一個(gè)Three.js的模型添加標(biāo)簽缕题,標(biāo)簽可以通過(guò)一個(gè)包含文字圖形信息的HTML元素或者一個(gè)three.js的精靈模型來(lái)表示侯勉。

常見(jiàn)問(wèn)題

  • three.js三維模型如何添加注釋文字秘症?
  • Three.js模型對(duì)象如何設(shè)置標(biāo)簽?
  • three.js如何用HTML元素設(shè)置顯示熱點(diǎn)
  • 如何把模型的世界坐標(biāo)轉(zhuǎn)化為屏幕坐標(biāo)?

每個(gè)人的基礎(chǔ)不同偏螺,雖然知識(shí)點(diǎn)區(qū)別不大,可能描述的時(shí)候會(huì)有很大區(qū)別矾瑰。

視頻講解和源碼

下面對(duì)知識(shí)點(diǎn)簡(jiǎn)單介紹,關(guān)于視頻講解可以關(guān)注我博客發(fā)布可的相關(guān)課程隘擎,個(gè)人WebGL/Three.js技術(shù)博客殴穴。

層級(jí)模型

復(fù)雜的項(xiàng)目,一個(gè)three.js場(chǎng)景往往包含包含多個(gè)模型對(duì)象货葬,模型對(duì)象也會(huì)有一些父對(duì)象采幌,這樣就會(huì)形成一個(gè)層級(jí)模型,從數(shù)據(jù)結(jié)構(gòu)的角度來(lái)看就是樹(shù)結(jié)構(gòu)震桶。
一個(gè)模型相對(duì)世界坐標(biāo)系原點(diǎn)的位置是世界坐標(biāo)休傍,相對(duì)父對(duì)象的位置是局部坐標(biāo)。

獲取模型位置

你如果想給一個(gè)模型設(shè)置標(biāo)簽蹲姐,首先需要獲得模型在世界坐標(biāo)系中所在的位置磨取,如果你希望標(biāo)注一個(gè)模型的某個(gè)局部位置,那就要獲得該局部區(qū)域的一個(gè)頂點(diǎn)坐標(biāo)柴墩。

  • .position屬性是一個(gè)模型的局部位置忙厌,相對(duì)父對(duì)象的位置,如果一個(gè)網(wǎng)格模型Mesh直接屬于場(chǎng)景Scene江咳,沒(méi)有除了Scene意外的父對(duì)象
  • .vertices如果幾何體是Geometry類型逢净,可以通過(guò).vertices屬性訪問(wèn)頂點(diǎn),通過(guò)下標(biāo)可以訪問(wèn)具體的頂點(diǎn)位置坐標(biāo)歼指。
  • .attributes.position如果幾何體是BufferGeometry類型爹土,可以通過(guò).attributes.position屬性訪問(wèn)頂點(diǎn)位置數(shù)據(jù)。
  • .getWorldPosition()實(shí)際項(xiàng)目中一個(gè)模型對(duì)象可以有多個(gè)父對(duì)象踩身,這個(gè)時(shí)候想獲得該模型對(duì)象的世界坐標(biāo)胀茵,就不能通過(guò).position屬性,應(yīng)該通過(guò).getWorldPosition()方法實(shí)現(xiàn)挟阻,該方法的使用參考基類Object3D宰掉。

實(shí)際項(xiàng)目中獲得一個(gè)模型,可能是通過(guò)點(diǎn)擊獲得赁濒,或者遍歷對(duì)象根據(jù)屬性值找到某個(gè)或某些模型轨奄,等等這里不展開(kāi)說(shuō),這不是本節(jié)課的重點(diǎn)拒炎,關(guān)于遞歸遍歷模型或者鼠標(biāo)點(diǎn)擊選中某個(gè)模型可以關(guān)注課程的其它部分挪拟。

精靈模型Sprite作為標(biāo)簽

在使用精靈模型表示標(biāo)簽之前,你應(yīng)該先了解精靈模型Sprite有什么特點(diǎn)击你。使用精靈模型表示一個(gè)模型對(duì)象的標(biāo)簽玉组,那么精靈模型就要位于模型對(duì)象的附近谎柄。可以獲得要標(biāo)注模型的世界坐標(biāo)惯雳,然后來(lái)設(shè)置精靈標(biāo)簽的位置朝巫,適當(dāng)偏移一點(diǎn)就可以,當(dāng)然也可以把精靈對(duì)象插入到模型對(duì)象的父對(duì)象中石景,和模型對(duì)象一樣作為父對(duì)象的子對(duì)象劈猿,這樣的話如果模型父對(duì)象的位置變化,精靈模型可以跟著一起變化潮孽。

標(biāo)簽的樣式可以讓美術(shù)設(shè)計(jì)好直接作為精靈的貼圖就可以揪荣,如果標(biāo)簽不是特定的,比如用戶輸入文字往史,平臺(tái)自動(dòng)生成模型標(biāo)簽仗颈,可以通過(guò)程序自動(dòng)化合成一個(gè)紋理作為精靈模型的貼圖,關(guān)于如何自動(dòng)合成紋理貼圖這里不詳細(xì)闡述椎例。

/**
 * 創(chuàng)建點(diǎn)精靈模型
 */
// 創(chuàng)建精靈材質(zhì)對(duì)象SpriteMaterial
var spriteMaterial = new THREE.SpriteMaterial({
  map:  new THREE.TextureLoader().load("立方體.png"), //設(shè)置精靈紋理貼圖
  transparent: true,//開(kāi)啟透明(紋理圖片png有透明信息)
});
// 創(chuàng)建精靈模型對(duì)象挨决,不需要幾何體geometry參數(shù)
var sprite = new THREE.Sprite(spriteMaterial);
sprite.scale.set(30, 30, 1); //精靈大小
// 把精靈模型插入到模型對(duì)象的父對(duì)象下面
group.add( sprite);
// 父對(duì)象group位置變化,網(wǎng)格模型及其對(duì)象的標(biāo)簽同樣發(fā)生變化
group.position.set(10, 0, -80);
// 表示標(biāo)簽信息的精靈模型對(duì)象相對(duì)父對(duì)象設(shè)置一定的偏移
sprite.translateY(30);

div等html元素作為標(biāo)簽(世界坐標(biāo)轉(zhuǎn)屏幕坐標(biāo))

通過(guò)html元素表示標(biāo)簽相比較使用精靈來(lái)說(shuō)比較麻煩,需要進(jìn)行坐標(biāo)變換订歪,一個(gè)模型顯示在Canvas畫(huà)布上凰棉,經(jīng)過(guò)了相機(jī)的視圖、投影變換陌粹,如果想把一個(gè)div元素標(biāo)注在一個(gè)模型附近撒犀,就需要計(jì)算模型渲染到畫(huà)布上的具體位置,也就是所謂的屏幕坐標(biāo)掏秩。使用html元素的好處是可以直接輸入漢字或舞,利用css來(lái)設(shè)置一下標(biāo)簽的樣式,當(dāng)然也可以直接加載美術(shù)設(shè)計(jì)的標(biāo)簽蒙幻。

世界坐標(biāo)轉(zhuǎn)WebGL標(biāo)準(zhǔn)設(shè)備坐標(biāo)

  • 世界坐標(biāo):世界坐標(biāo)簡(jiǎn)單說(shuō)就是模型在three.js三維空間中的位置映凳,但是注意不是局部位置屬性.position,你可以通過(guò).getWorldPosition()方法獲得世界坐標(biāo)邮破,每個(gè)子對(duì)象都有一個(gè)相對(duì)父對(duì)象的位置诈豌,把一個(gè)對(duì)象的所有父對(duì)象相對(duì)Scene坐標(biāo)原點(diǎn)的位置加起來(lái)就是一個(gè)模型的世界坐標(biāo)
  • 屏幕坐標(biāo):你可以理解為Canvas畫(huà)布上的位置,單位是像素px抒和,這和HTML說(shuō)的像素是一樣的矫渔。
//創(chuàng)建一個(gè)三維向量作為世界坐標(biāo)
var worldVector = new THREE.Vector3();
//獲取網(wǎng)格模型boxMesh的世界坐標(biāo),賦值給worldVector
boxMesh.getWorldPosition(worldVector);
//世界坐標(biāo)轉(zhuǎn)標(biāo)準(zhǔn)設(shè)備坐標(biāo)摧莽,standardVector是WebGL設(shè)備坐標(biāo)
var standardVector = worldVector.project(camera);

.project()是向量Vector3的方法庙洼,一個(gè)表示位置的向量Vector3把相機(jī)作為參數(shù)執(zhí)行該方法可以得到經(jīng)過(guò)相機(jī)變換后的坐標(biāo)。一般threejs渲染器渲染的時(shí)候,會(huì)自動(dòng)從相機(jī)對(duì)象讀取視圖和投影矩陣對(duì)模型的頂點(diǎn)進(jìn)行變換油够。

WebGL標(biāo)準(zhǔn)設(shè)備坐標(biāo)轉(zhuǎn)屏幕坐標(biāo)

Canvas全屏顯示的時(shí)候復(fù)合下面的計(jì)算規(guī)則蚁袭,如果不是全屏要注意修改計(jì)算規(guī)則。如果不是全屏石咬,計(jì)算a和b的值揩悄,不能使用window.innerWidth,而應(yīng)該使用canvas的具體寬高鬼悠。如果canvas是局部顯示相對(duì)body區(qū)域的左上角有偏移删性,那么div元素也要設(shè)置一定的偏移。

// 根據(jù)WebGL標(biāo)準(zhǔn)設(shè)備坐標(biāo)standardVector計(jì)算div標(biāo)簽在瀏覽器頁(yè)面的坐標(biāo)
var a = window.innerWidth / 2;
var b = window.innerHeight / 2;
var x = Math.round(standardVector.x * a + a); //標(biāo)準(zhǔn)設(shè)備坐標(biāo)轉(zhuǎn)屏幕坐標(biāo)
var y = Math.round(-standardVector.y * b + b); //標(biāo)準(zhǔn)設(shè)備坐標(biāo)轉(zhuǎn)屏幕坐標(biāo)
/**
 * 設(shè)置標(biāo)簽元素的位置
 */
div.style.left = x + 'px';
//這里的130px主要是為了標(biāo)簽和模型有一定偏移厦章,當(dāng)然也可以不設(shè)置镇匀,兩者疊加在一起
div.style.top = y - 130 + 'px';
screen.png
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末照藻,一起剝皮案震驚了整個(gè)濱河市袜啃,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌幸缕,老刑警劉巖群发,帶你破解...
    沈念sama閱讀 206,602評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異发乔,居然都是意外死亡熟妓,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,442評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門栏尚,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)起愈,“玉大人,你說(shuō)我怎么就攤上這事译仗√洌” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,878評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵纵菌,是天一觀的道長(zhǎng)阐污。 經(jīng)常有香客問(wèn)我,道長(zhǎng)咱圆,這世上最難降的妖魔是什么笛辟? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,306評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮序苏,結(jié)果婚禮上手幢,老公的妹妹穿的比我還像新娘。我一直安慰自己忱详,他們只是感情好弯菊,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,330評(píng)論 5 373
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著,像睡著了一般管钳。 火紅的嫁衣襯著肌膚如雪钦铁。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,071評(píng)論 1 285
  • 那天才漆,我揣著相機(jī)與錄音牛曹,去河邊找鬼。 笑死醇滥,一個(gè)胖子當(dāng)著我的面吹牛黎比,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播鸳玩,決...
    沈念sama閱讀 38,382評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼阅虫,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了不跟?” 一聲冷哼從身側(cè)響起颓帝,我...
    開(kāi)封第一講書(shū)人閱讀 37,006評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎窝革,沒(méi)想到半個(gè)月后购城,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,512評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡虐译,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,965評(píng)論 2 325
  • 正文 我和宋清朗相戀三年瘪板,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片漆诽。...
    茶點(diǎn)故事閱讀 38,094評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡侮攀,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出厢拭,到底是詐尸還是另有隱情兰英,我是刑警寧澤,帶...
    沈念sama閱讀 33,732評(píng)論 4 323
  • 正文 年R本政府宣布蚪腐,位于F島的核電站箭昵,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏回季。R本人自食惡果不足惜家制,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,283評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望泡一。 院中可真熱鬧颤殴,春花似錦、人聲如沸鼻忠。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,286評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至矮瘟,卻和暖如春瞳脓,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背澈侠。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,512評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工劫侧, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人哨啃。 一個(gè)月前我還...
    沈念sama閱讀 45,536評(píng)論 2 354
  • 正文 我出身青樓烧栋,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親拳球。 傳聞我的和親對(duì)象是個(gè)殘疾皇子审姓,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,828評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容