最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

Three.js 進(jìn)階之旅:全景漫游-高階版在線看房

2023-04-10 19:32 作者:unlexx  | 我要投稿

聲明:本文涉及圖文和模型素材僅用于個(gè)人學(xué)習(xí)、研究和欣賞,請(qǐng)勿二次修改、非法傳播、轉(zhuǎn)載、出版、商用、及進(jìn)行其他獲利行為。


摘要

專欄上篇文章《Three.js 進(jìn)階之旅:全景漫游-初階移動(dòng)相機(jī)版》中通過(guò)創(chuàng)建多個(gè)球體全景場(chǎng)景并移動(dòng)相機(jī)和控制器的方式實(shí)現(xiàn)了多個(gè)場(chǎng)景之間的穿梭漫游。這種方式的缺點(diǎn)也是顯而易見(jiàn)的,隨著全景場(chǎng)景的增加來(lái)創(chuàng)建對(duì)應(yīng)數(shù)量的球體,使得空間關(guān)系計(jì)算難度提升,并且大幅降低瀏覽器渲染行性能。在上一篇文章的基礎(chǔ)上,本文通過(guò)以下幾點(diǎn)對(duì)全景功能加以優(yōu)化,最后實(shí)現(xiàn)一個(gè)可以應(yīng)用到實(shí)際項(xiàng)目中的在線看房案例。通過(guò)閱讀本文和實(shí)踐案例,你將學(xué)到的知識(shí)包括:使用?Three.js?用新的技術(shù)思路實(shí)現(xiàn)多個(gè)場(chǎng)景的加載和場(chǎng)景間的絲滑過(guò)渡切換、隨著空間一直和角度實(shí)時(shí)變化的房源小地圖、在全景場(chǎng)景中添加如地面指引、空間物體展示、房間標(biāo)注等多種類型的交互熱點(diǎn)等

效果

我們先來(lái)看看本文在線看房案例的最終實(shí)現(xiàn)效果,頁(yè)面主體由代表多個(gè)房間的全景圖????、全景空間中的用于標(biāo)識(shí)物體的交互熱點(diǎn)????、顯示房間名稱的空間熱點(diǎn)?????、用于地面前進(jìn)指引的交互熱點(diǎn)????、固定在側(cè)邊的房間切換按鈕????以及右上側(cè)的房間小地圖????構(gòu)成。左右拖動(dòng)頁(yè)面可以進(jìn)行當(dāng)前房間的全景預(yù)覽,同時(shí)小地圖上的錨點(diǎn)旋轉(zhuǎn)角度和位置也根據(jù)當(dāng)前房間的位置和旋轉(zhuǎn)角度的變化而變化,使用鼠標(biāo)滾輪或觸摸板放大縮小頁(yè)面可以查看房間全景圖的整體和局部細(xì)節(jié)。

點(diǎn)擊地面前進(jìn)指引標(biāo)記熱點(diǎn)或空間中的房間名標(biāo)簽熱點(diǎn)、以及固定在右邊的房間名按鈕時(shí)可以絲滑切換到對(duì)應(yīng)的房間,固定在右側(cè)的按鈕和空間中的房間名標(biāo)簽之間相互聯(lián)動(dòng),當(dāng)頁(yè)面視區(qū)無(wú)法看到空間中的房間名標(biāo)簽時(shí),它會(huì)自動(dòng)固定到右側(cè)按鈕處。點(diǎn)擊房間中的物體標(biāo)識(shí)熱點(diǎn)可以與之產(chǎn)生交互。

打開(kāi)以下鏈接,在線預(yù)覽效果,gif?造成丟幀和畫(huà)質(zhì)損失,在線大屏訪問(wèn)效果更佳。

  • ??????在線預(yù)覽地址:https://dragonir.github.io/panorama-advanced/

本專欄系列代碼托管在?Github?倉(cāng)庫(kù)【threejs-odessey】,后續(xù)所有目錄也都將在此倉(cāng)庫(kù)中更新。

???代碼倉(cāng)庫(kù)地址:git@github.com:dragonir/threejs-odessey.git

原理

對(duì)比上篇有哪些優(yōu)化點(diǎn)

看完本文在線看房案例,我們先來(lái)總結(jié)下本文在上篇文章示例的基礎(chǔ)上,做了哪些優(yōu)化?下圖幾個(gè)標(biāo)注點(diǎn)對(duì)應(yīng)本文實(shí)現(xiàn)的一些新的功能和優(yōu)化,通過(guò)以下幾點(diǎn)的實(shí)現(xiàn)可以提升多個(gè)全景場(chǎng)景漫游項(xiàng)目的加載渲染性能和用戶體驗(yàn)。

  • :是指使用新的技術(shù)思路加載多個(gè)全景圖場(chǎng)景,并使用著色器實(shí)現(xiàn)多個(gè)場(chǎng)景之間的優(yōu)雅過(guò)渡。

  • :是用于標(biāo)注室內(nèi)物體的空間交互熱點(diǎn),點(diǎn)擊可以實(shí)現(xiàn)交互。

  • :是固定于頁(yè)面?zhèn)冗叺那袚Q空間按鈕,只有懸浮在空間中的房間標(biāo)簽看不見(jiàn)的時(shí)候,對(duì)應(yīng)的房間切換按鈕才會(huì)顯示。

  • :是懸浮在空間中的房間標(biāo)簽,當(dāng)旋轉(zhuǎn)場(chǎng)景看不見(jiàn)它的時(shí)候,它會(huì)固定到處,形成空間的標(biāo)簽和固定在側(cè)邊的標(biāo)簽之間是相互聯(lián)動(dòng)的視覺(jué)效果。

  • :是地面場(chǎng)景切換指引熱點(diǎn),點(diǎn)擊地面的熱點(diǎn)可以切換到下個(gè)場(chǎng)景,視覺(jué)上形成在空間中前進(jìn)的效果。

  • :是表示整個(gè)房子的小地圖,在全景空間中旋轉(zhuǎn)或者全景漫游時(shí),圖中的錨點(diǎn)的方向和位置會(huì)對(duì)應(yīng)改變。

房間場(chǎng)景切換原理

上篇文章示例我們通過(guò)創(chuàng)建多個(gè)球體移動(dòng)相機(jī)和控制器的方式實(shí)現(xiàn)多個(gè)全景場(chǎng)景之間的漫游,而這篇文章中,我們將通過(guò)創(chuàng)建多個(gè)場(chǎng)景的方式,來(lái)實(shí)現(xiàn)兩個(gè)全景場(chǎng)景之間的過(guò)渡漫游效果。

實(shí)現(xiàn)原理示意圖如下所示,頁(yè)面總共將創(chuàng)建?3?個(gè)場(chǎng)景,origin?表示當(dāng)前場(chǎng)景,destination?表示目標(biāo)場(chǎng)景,利用當(dāng)前場(chǎng)景和目標(biāo)場(chǎng)景合成用于展示過(guò)渡效果的?transition?過(guò)渡場(chǎng)景,當(dāng)點(diǎn)擊切換房間按鈕時(shí),三個(gè)場(chǎng)景的加載順便分別為?origin -> transition -> destiontion,由此在視覺(jué)上形成從上個(gè)房間切換到下個(gè)房間并且伴隨漸變過(guò)渡的場(chǎng)景漫游效果。

實(shí)現(xiàn)

對(duì)應(yīng)上面幾個(gè)優(yōu)化點(diǎn)及多個(gè)場(chǎng)景的切換原理,我們現(xiàn)在來(lái)一步步實(shí)現(xiàn)本文中的案例:

〇 場(chǎng)景初始化

我們先來(lái)看看頁(yè)面使用了哪些資源,OrbitControls?是鏡頭軌道控制器,可以在全景圖場(chǎng)景中使用鼠標(biāo)進(jìn)行旋轉(zhuǎn)和放大縮?。?code>TWEEN?和?Animations?用于實(shí)現(xiàn)一些鏡頭補(bǔ)間動(dòng)畫(huà)效果;rooms, markers, roomLabels?是自定義的數(shù)據(jù),分別表示房間信息、房間地面前進(jìn)指引標(biāo)記物和房間名稱熱點(diǎn)標(biāo)記物;fragment?和?vertex?是用于實(shí)現(xiàn)原始場(chǎng)景和目標(biāo)場(chǎng)景切換的動(dòng)畫(huà)過(guò)渡效果;TinyMap?是和當(dāng)前房間位置和鏡頭旋轉(zhuǎn)方向同步的小地圖組件。

初始化?Three.js?構(gòu)建三維場(chǎng)景的渲染器、場(chǎng)景、相機(jī)、控制器等基本元素,需要注意的是這次把場(chǎng)景命名為原場(chǎng)景?sceneOrigin,因?yàn)楹罄m(xù)還要場(chǎng)景多個(gè)場(chǎng)景,通過(guò)多個(gè)場(chǎng)景間的動(dòng)畫(huà)過(guò)渡效果,實(shí)現(xiàn)各個(gè)房間全景圖之間的穿梭漫游效果。

① 加載多個(gè)全景場(chǎng)景和全景漫游過(guò)渡

多個(gè)全景場(chǎng)景加載

現(xiàn)在來(lái)看看具體代碼實(shí)現(xiàn):創(chuàng)建原場(chǎng)景,并添加一個(gè)球體????作為當(dāng)前房間的全景圖;創(chuàng)建目標(biāo)場(chǎng)景,并添加一個(gè)球體????作為目標(biāo)場(chǎng)景的全景圖;創(chuàng)建過(guò)渡場(chǎng)景,并添加一個(gè)平面幾何體???到其中,該平面將用于展示原場(chǎng)景和目標(biāo)場(chǎng)景之間的過(guò)渡效果,幾何體采用?ShaderMaterial?著色器材質(zhì),并具有?progress、sceneOriginsceneDestination?三個(gè)由?JavaScript?傳遞到著色器的統(tǒng)一變量?uniforms。同時(shí)并創(chuàng)建了一個(gè)用于顯示過(guò)渡場(chǎng)景的?OrthographicCamera?正交相機(jī)。

然后在頁(yè)面重繪方法中依次渲染它們,并更新過(guò)渡場(chǎng)景中平面幾何體的材質(zhì)變量:

全景漫游絲滑過(guò)渡

創(chuàng)建完場(chǎng)景后,我們使用著色器來(lái)實(shí)現(xiàn)過(guò)渡場(chǎng)景的動(dòng)畫(huà)效果,在頂點(diǎn)著色器中我們添加如下的變量和方法:

在片段著色器中,我們使用從?JavaScript?中傳遞過(guò)來(lái)的變量?sceneOrigin?原場(chǎng)景、sceneDestination?目標(biāo)場(chǎng)景以及過(guò)渡進(jìn)度值?progress?作為參數(shù),實(shí)現(xiàn)兩個(gè)場(chǎng)景之間漸隱漸顯效果的過(guò)渡動(dòng)畫(huà)???:

我們甚至可以再添加一個(gè)?distort?方法,實(shí)現(xiàn)華麗的穿梭效果:

此時(shí)我們就可以使用一個(gè)數(shù)組向下面這樣批量定義好所有房間的路徑,如從走廊可以通向臥室、客廳,用?currentRoom?和?destinationRoom?字段標(biāo)識(shí)當(dāng)前房間和目標(biāo)房間,當(dāng)觸發(fā)切換房間動(dòng)作時(shí),我們用這兩個(gè)字段拿到對(duì)應(yīng)的全景貼圖,然后更新原始場(chǎng)景????和 目標(biāo)場(chǎng)景????中球體的材質(zhì)屬性?map?即可實(shí)現(xiàn)房間切換了。

???關(guān)于著色器入門(mén),可以看看此專欄另一篇文章《Three.js 進(jìn)階之旅:Shader著色器入門(mén)》

② 創(chuàng)建標(biāo)注室內(nèi)物體的交互熱點(diǎn)

室內(nèi)的交互熱點(diǎn),即在三維空間中添加的平面交互點(diǎn),可以通過(guò)?Sprite、Canvas?等實(shí)現(xiàn),但是它們的缺點(diǎn)是樣式不容易改,本文中所有的交互熱點(diǎn)都是使用頁(yè)面的?DOM?節(jié)點(diǎn)實(shí)現(xiàn)的,因此直接使用?CSS?就能自由修改樣式。

我們可以在房間數(shù)據(jù)中向下面這樣配置標(biāo)注室內(nèi)物體的交互點(diǎn)信息和?Vector3?類型的位置信息,然后使用數(shù)組在頁(yè)面上批量創(chuàng)建?DOM?節(jié)點(diǎn):

在頁(yè)面中這樣渲染它們:

為了實(shí)現(xiàn)絲滑的擴(kuò)散效果動(dòng)畫(huà),室內(nèi)物體標(biāo)記熱點(diǎn)使用了一張雪碧圖作為動(dòng)畫(huà)幀,可以像下面這樣播放雪碧圖動(dòng)畫(huà)幀:

為了交互熱點(diǎn)能夠顯示在按配置好的位置屬性?position?正確顯示在頁(yè)面上,我們還需要在頁(yè)面重回方法?tick()?中實(shí)時(shí)更新它們的位置,并利用?Raycaster?檢測(cè)標(biāo)記點(diǎn)是否被遮擋來(lái)顯示或隱藏交互點(diǎn)。

???本文中其他交互點(diǎn)如房間標(biāo)簽名標(biāo)記點(diǎn)、地面前進(jìn)指引標(biāo)記點(diǎn)等與室內(nèi)物體標(biāo)注交互點(diǎn)的實(shí)現(xiàn)原理都是一樣的,后續(xù)將不再贅述。

③ 創(chuàng)建側(cè)邊固定房間切換按鈕

固定在側(cè)邊的按鈕用保存房間信息的數(shù)組?rooms?即可生成,我們可以使用?v-show?或?v-if?對(duì)房間標(biāo)簽進(jìn)行過(guò)濾,當(dāng)我們的全景圖處于當(dāng)前房間時(shí),就可以不顯示當(dāng)前房間的標(biāo)簽名。如下圖中,當(dāng)前位置是走廊的全景空間,切換按鈕處就僅顯示走廊以外的其他房間的切換按鈕。

④ 創(chuàng)建三維空間房間標(biāo)簽并與側(cè)邊標(biāo)簽聯(lián)動(dòng)

空間房間標(biāo)簽

為了在三維全景空間中漫游時(shí)清晰地知道各個(gè)房間在當(dāng)前房間的哪個(gè)位置,我們可以向?qū)崿F(xiàn)室內(nèi)物體交互熱點(diǎn)一樣,在三維空間中添加房間標(biāo)簽名標(biāo)記點(diǎn)。比如當(dāng)我們位于客廳時(shí),從客廳可以看到廚房和走廊,此時(shí)我們就可以向下面這樣在客廳空間中配置廚房和走廊名稱的房間名稱標(biāo)記點(diǎn),然后像添加室內(nèi)物體標(biāo)記熱點(diǎn)地原理一樣,在空間中創(chuàng)建對(duì)應(yīng)的?html?標(biāo)簽并在?tick()?方法中更新每個(gè)標(biāo)簽的顯示隱藏屬性即可。

與側(cè)邊標(biāo)簽聯(lián)動(dòng)

當(dāng)我們完成上兩個(gè)步驟時(shí),以當(dāng)前房間位于客廳為例,此時(shí)頁(yè)面上就會(huì)顯示兩個(gè)一樣的房間標(biāo)簽名:側(cè)邊固定按鈕處有走廊,隨空間轉(zhuǎn)動(dòng)的浮動(dòng)房間標(biāo)簽熱點(diǎn)中也有走廊,同時(shí)出現(xiàn)兩個(gè)相同的名稱就會(huì)使頁(yè)面變得混亂,讓使用的地人產(chǎn)生疑惑。

我們可以像這樣優(yōu)化以下這個(gè)功能:當(dāng)位于空間中的房間名稱標(biāo)簽在可見(jiàn)時(shí),就從側(cè)邊固定按鈕標(biāo)簽中將其移除;當(dāng)位于空間中的房間名稱標(biāo)簽轉(zhuǎn)動(dòng)到后方不可見(jiàn)時(shí),側(cè)邊固定按鈕處就顯示該房間名稱。代碼中我們可以在?tick()?方法中像下面這樣實(shí)現(xiàn),初始化時(shí)我們對(duì)?rooms?數(shù)組的每一項(xiàng)設(shè)置一個(gè)屬性?visible: true,當(dāng)在頁(yè)面重繪動(dòng)畫(huà)中檢測(cè)到某房間名稱標(biāo)記點(diǎn)轉(zhuǎn)出屏幕時(shí),就將該標(biāo)簽代表的房間的?visible?屬性設(shè)置為?false,當(dāng)該標(biāo)簽跟隨房間轉(zhuǎn)動(dòng)再次出現(xiàn)在屏幕上時(shí),就將?visible?修改為?true

然后,我們?cè)侔研薷南律晒潭ㄔ趥?cè)邊的房間按鈕的方法,用過(guò)濾過(guò)的房間數(shù)組數(shù)組?filtederRooms?代替之前的?rooms,并判斷該標(biāo)簽不是當(dāng)前所處的的房間且該房間的可見(jiàn)性為?true?時(shí)才顯示該側(cè)邊固定按鈕。

此時(shí),視覺(jué)上就會(huì)形成當(dāng)我們轉(zhuǎn)動(dòng)房間全景場(chǎng)景時(shí),如果位于空間的房間名稱標(biāo)簽轉(zhuǎn)出到屏幕之外時(shí),就會(huì)自動(dòng)固定到側(cè)邊的視覺(jué)效果????。

⑤ 創(chuàng)建地面指引熱點(diǎn)

在地面上添加前進(jìn)指引熱點(diǎn),可以引導(dǎo)用戶從當(dāng)前空間漫游穿梭到其他空間,利用上面步驟①中定義好的數(shù)組?routes,我們?cè)谄渲刑砑右粋€(gè)地面熱點(diǎn)在三維空間中的?Vector3?類型位置點(diǎn)信息,然后和前面創(chuàng)建室內(nèi)物體標(biāo)注交互點(diǎn)一樣,批量創(chuàng)建即可。

⑥ 創(chuàng)建小地圖

在線看房????頁(yè)面最重要的特征就是有戶型小地圖???,用戶可以清晰地知道該房源的詳細(xì)結(jié)構(gòu)以及當(dāng)前所處的房間位置,當(dāng)隨著房間全景圖在三維空間中旋轉(zhuǎn),位于小地圖上的錨點(diǎn)????也對(duì)應(yīng)旋轉(zhuǎn)和移動(dòng)。

我們來(lái)看看具體是如何實(shí)現(xiàn)的:我們先創(chuàng)建一個(gè)?TinyMap.vue?組件,其中?rotate?屬性用來(lái)設(shè)置小地圖上錨點(diǎn)的旋轉(zhuǎn)方向,position?屬性用來(lái)設(shè)置錨點(diǎn)所處的位置,然后使用父組件傳來(lái)的兩者的值,使用?CSS?即可實(shí)現(xiàn)小地圖錨點(diǎn)的位置和方向?qū)崟r(shí)變化。

至于?rotate?和?position?的獲取,我們需要在父組件中這樣來(lái)實(shí)現(xiàn),rotate?即相機(jī)和軌道控制器之前形成的夾角度數(shù),我們可以在動(dòng)畫(huà)方法?tick()?中,使用?camera?和controls?的?x軸?和?z軸?的參數(shù),按下面公式計(jì)算出兩者之間的夾角,并轉(zhuǎn)換成子組件中需要的弧度類型。position?的獲取就非常簡(jiǎn)單,我們先在?rooms?中配置好每個(gè)房間固定到?left?和?top?值,然后拿到當(dāng)前房間的值,傳給?TinyMap?組件即可。

小地圖中錨點(diǎn)的位置隨著看房視角的變化而旋轉(zhuǎn)和移動(dòng)。

⑦ 頁(yè)面優(yōu)化

整個(gè)在線看房????項(xiàng)目的主要功能到這里已經(jīng)全部介紹完了,實(shí)際項(xiàng)目中可能一個(gè)房源不止?5?個(gè)房間全景圖,加之?HDR?全景圖的體積也比較大,因此圖片預(yù)加載和項(xiàng)目加載進(jìn)度管理是非常有必要的,我們可以對(duì)其進(jìn)一步進(jìn)行優(yōu)化,提升用戶體驗(yàn)??。

???源碼地址:?https://github.com/dragonir/threejs-odessey

總結(jié)

本文中主要包含的知識(shí)點(diǎn)包括:

  • Three.js?三維全景場(chǎng)景初始化

  • 加載多個(gè)全景場(chǎng)景,并實(shí)現(xiàn)絲滑的全景圖之間的漫游過(guò)渡效果

  • 在三維全景空間中添加可交互的標(biāo)記熱點(diǎn),如房間標(biāo)簽名熱點(diǎn)、室內(nèi)物體介紹熱點(diǎn)、地面前進(jìn)指引熱點(diǎn)等

  • 學(xué)會(huì)三維空間中熱點(diǎn)的顯示隱藏可見(jiàn)性檢測(cè),并利用可見(jiàn)性檢測(cè)實(shí)現(xiàn)視覺(jué)上空間熱點(diǎn)側(cè)邊自動(dòng)??抗δ?/p>

  • 通過(guò)實(shí)時(shí)計(jì)算攝像機(jī)與控制器的夾角,來(lái)實(shí)現(xiàn)在線看房小地圖。

想了解其他前端知識(shí)或其他未在本文中詳細(xì)描述的Web 3D開(kāi)發(fā)技術(shù)相關(guān)知識(shí),可閱讀我往期的文章。如果有疑問(wèn)可以在評(píng)論中留言,如果覺(jué)得文章對(duì)你有幫助,不要忘了一鍵三連哦 ??。

參考

  • [1].?threejs.org


Three.js 進(jìn)階之旅:全景漫游-高階版在線看房的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國(guó)家法律
佛教| 探索| 光泽县| 高邑县| 磐安县| 古田县| 紫金县| 和平县| 普兰店市| 富锦市| 佛坪县| 奉节县| 安岳县| 正定县| 景东| 长阳| 嘉义市| 定日县| 开阳县| 惠来县| 蛟河市| 洛宁县| 五常市| 中超| 永定县| 石景山区| 宜兰县| 岳普湖县| 太康县| 盘山县| 彭水| 瓮安县| 弋阳县| 高平市| 龙里县| 乐都县| 潍坊市| 民丰县| 衡阳县| 孝昌县| 武定县|