小窺React360——用React創建360全景VR體驗

来源:https://www.cnblogs.com/venoral/archive/2019/05/23/10914222.html
-Advertisement-
Play Games

前言 混跡VR屆的發燒友兼開發者們一定不要錯過這款FaceBook推出的跨端VR開發框架——React360,稱為360全景體驗框架更為準確,因為其前身是FaceBook和Oculus2017年發佈的一個叫作“Racet VR”的JS庫,用來在web端創建3D和VR體驗。後來Oculus使用該框架的 ...


前言   

混跡VR屆的發燒友兼開發者們一定不要錯過這款FaceBook推出的跨端VR開發框架——React360,稱為360全景體驗框架更為準確,因為其前身是FaceBook和Oculus2017年發佈的一個叫作“Racet VR”的JS庫,用來在web端創建3D和VR體驗。後來Oculus使用該框架的原生C++版本構建自己部分應用,隨著時間推移,由於要求框架解決不同需求,項目的APIs開始發生分叉。為了避免兩個系統的混淆,開源框架重命名為React360,這更好地反映它的使用場景:創建橫跨PC,移動端,VR設備上的沉浸式360體驗。

可以先看一下官方示例效果,這是一個稍複雜的應用,加入了3D模型,在3D模型和2D面板間共用數據。

體驗

工作原理

官方提供了構建工具react-360-cli,內部使用和ReactNative一樣的打包工具Metro,基於JS Bundle在自己的JS Runtime中進行解析,通過事件機制與客戶端通信,其實該框架還有很多方面相像或依賴於RN。構建一個React360應用程式需要完成兩部分,需要渲染的Raect組件和Runtime定義(這種角色劃分直接借鑒於React Native)。這也很清楚地反映出React360的工作流程,可以參見下圖:
(工作流程圖)

基於JavaScript Core/V8引擎,React360提供了Runtime需要的APIs,在客戶端(頭戴設備,移動端,瀏覽器等)完成構建界面,web端的渲染底層依賴於Three.js,這是業界較為成熟的3D圖形框架,一般需要手動設置3D網格和紋理,而框架中的react-360-web模塊隱藏了這些細節。當創建了新的React組件,框架會指示Runtime將它們添加到3D場景中,當用戶提供輸入將作為事件通過Runtime傳遞給React,這兩部分相互合作形成一個凝合系統。如果想在系統中分享數據,就需要藉助框架提供的Native Modules。

需要註意的是,由於JS運作在瀏覽器中是單線程的,應用中任何阻礙行為都有可能造成渲染延遲,這對於VR這種即時性很強的體驗是十分致命的,所以框架將React組件和渲染過程放在分離的上下文中情有可原。

預設情況下,React360使用Web Worker執行你的React代碼,而不是標準瀏覽器,這就意味著在組件定義的文件中訪問不到原生window.location這類APIs。並不是嚴格意義上的無法訪問,事實上當你列印window對象時React360提供了一個DedicatedWorkerGlobalScope類型實例,它包裝了window的一些內容。

Surfaces
Surfaces實際上是一個載體,允許你添加2D內容到3D場景,開發者依據像素定義Surfaces寬高,React360獲取信息產生合適尺寸的對象,官方介紹了兩種類型的Surfaces,Cylinder和Flat。一個Cylinder Surface讓2D內容投射到半徑為4m的Cylinder內部,其實是假想的圓柱模式。一個Flat Surface位於4m半徑的球體外側,一個假想的球體模式。APIs也提供了像yaw(垂搖),pitch(縱搖),roll(橫搖)這些物體自由度控制信息。

為了將React組建附著在Surface上,需要使用AppRegistry註冊組件,又一次與ReactNative相似。這會告知Runtime你的組件通過id欄位被唯一確定。

AppRegistry.registerComponent('MyAppName', () => MyAppName);

同時在Runtime文件中引用。

r360.renderToSurface(
  r360.createRoot('MyAppName'),
  r360.getDefaultSurface(),
  'default' /* 可選項,引用的surface的名稱 */
);

Components

官方提供了呈現2D,3D內容的展示組件和交互按鈕組件。

  • View:UI構建最基本的元素,被用來組織實體或其他View元素,也是輸入事件的容器。
  • Image:呈現2D圖像
  • ENtity:渲染3D對象,支持obj,mtl,gltf格式文件
  • VrButton:是一個實用程式類,是捕獲事件的包裝器。可以檢測各種輸入設備上單擊類型操作,這是通過一個可以監聽按鍵事件的內部狀態機做到的。

Layout 

支持2D Surface佈局,完全以Flexbox格式佈局,又是一個和RN相似的點。支持3D Space佈局,使用Entity組件時候,通過transform完成3D對象放置,x軸指向用戶右側,y軸指向上方,z軸指向用戶後方。

APIs
官方提供了常見的APIs,例如來自React Native的Animated;鍵值對存儲系統AsyncStorage;值得一提的是提供的ControllerInfo可以被用來響應控制器的connect/disconnect事件,獲取關於所連接的游戲手柄和控制器的靜態信息,比如唯一標識符,按鈕,軸數等信息。環境API Environment用來改變場景的背景,包括圖片,音頻,視頻。

實例解讀

利用react-360-cli生成的項目中主要有這三個文件:

  • index.js:放置應用的主要代碼,React組件的地方,在這裡可以組織拆分多個組件
  • client.js:也就是Runtime的配置,這部分連接瀏覽器環境和React應用。根據代碼示例看到主要完成三件事:(1)創建React360一個新實例,載入並附加React代碼到DOM特定位置,這裡也是傳遞初始化選項的地方。(2)將你的代碼掛載到3D場景中,在index.js中聲明的掛載點附著在應用程式的預設曲面。(3)添加背景信息,這個部分可選,允許代碼仍在載入過程中展示圖片,讓用戶儘快看到一些內容。
  • index.html:提供安裝JS代碼的掛載點。
 1 import {ReactInstance} from 'react-360-web';
 2 
 3 function init(bundle, parent, options = {}) {
 4   const r360 = new ReactInstance(bundle, parent, {
 5     fullScreen: true,
 6     ...options,
 7   });
 8 
 9   r360.renderToSurface(
10     r360.createRoot('SlideshowSample', {
11       photos: [
12         {uri: './static_assets/360_world.jpg', title: '360 World1', format: '2D'},
13         {uri: './static_assets/360_world2.jpg', title: '360 World2', format: '2D'},
14         // Add your own 180 / 360 photos to this array,
15         // with an associated title and format
16       ],
17     }),
18     r360.getDefaultSurface(),
19   );
20 }
21 
22 window.React360 = {init};

Native Modules

前面說過React組件運行在單獨上下文中,那麼如何與主視窗通信,官方提供了Native Modules模塊,讓React代碼有了回調到Runtime的能力,包括在載入中存值,請求有關連接控制器信息或操縱渲染環境。Native模塊被創建在Runtime代碼中,使用Native Module需要自定義類,繼承自Module,使用前需註冊,這個示例模板代碼演示了Native Modules的許多用法

 1 import {Module} from 'react-360-web';
 2 
 3 class MyModule extends Module {
 4   constructor() {
 5     // 使這個模塊在NativeModules.MyModule可用
 6     super('MyModule'); 
 7   }
 8   
 9   // 這個方法將被暴露到React應用一側
10   doSomething() {
11 
12   }
13 }
14 
15 const r360 = new ReactInstance(
16   'MyApp.bundle?platform=vr',
17   document.getElementById('container'),
18   {
19     // 在初始時刻註冊自定義模塊,接收Native Module實例,或一個返回實例的函數(需要傳遞上下文)
20     nativeModules: [
21       new MyModule(),
22       ctx => new MyModule(ctx)
23     ]
24   }
25 );

通常有兩種使用場景,暴露常量和普通到React(同步),回調函數或返回Promise方法(非同步)。這一段代碼同時演示了這幾種使用場景,這是一個發送瀏覽器信息到React側的應用示例,在註冊階段,模塊構造時常量生成並添加模塊實例的userAgent屬性上,這個值被直接傳遞給React。第二個例子是暴露了同步setTitle()方法,只需要一個字元串設置視窗標題欄。剩下兩個非同步方法展示了非同步數據如何返回到React。當getBatteryLevel()在React側被調用,開發者傳遞的回調在數據可用時觸發,調用上下文提供的invokeCallback,將參數放置在數組中,你可以給回調傳遞任意數量的參數。儘管回調是處理非同步任務的一種方式,但我們更偏向於用Promise創建有組織可讀性強的非同步邏輯鏈。通過Native Module,你可以使用$符號首碼形式來暴露這種行為,兩個回調ID會作為Promise的resolve, reject自動傳遞給Runtime,該方法會返回一個Promise到調用端。

 1 import {Module} from 'react-360-web';
 2 
 3 export default class BrowserInfoModule extends Module {
 4   constructor(ctx) {
 5     super('BrowserInfo');
 6     this._rnctx = ctx;
 7     this.userAgent = navigator.userAgent;
 8   }
 9   /*

*/ 10 setTitle(title) { 11 document.title = title; 12 } 13 14 getBatteryLevel(cb) { // 讀取window信息 15 const getBattery = navigator.mozGetBattery || navigator.getBattery; 16 getBattery 17 .call(navigator) 18 .then( 19 battery => { 20 // extract the level and return it 21 return battery.level; 22 }, 23 e => { 24 // if an error occurs, return null 25 return null; 26 } 27 ) 28 .then(level => { 29 if (this._rnctx) { 30 this._rnctx.invokeCallback(cb, [level]); 31 } 32 }); 33 } 34 35 $getConfirmation(message, resolve, reject) { 36 const result = window.confirm(message); 37 if (this._rnctx) { 38 if (result) { 39 this._rnctx.invokeCallback(resolve, []); 40 } else { 41 // When rejecting a Promise, a message should be provided to populate 42 // the Error object on the React side 43 this._rnctx.invokeCallback(reject, [{message: 'Canceled the dialog'}]); 44 } 45 } 46 } 47 }

後記

對於React360的整體一覽,官方文檔還是對在web端介紹比較多,官方開發團隊在GitHub也比較活躍,所以有問題可以及時issue都會有人回覆。Facebook在幾年前收購了Oculus足已看出其進軍VR屆的雄心已經初見倪端,目前市面上許多APP對360全景圖的應用也萬象回春,微博的全景圖藉助手機的陀螺儀和重力感測器在不點擊圖片詳情的情況下跟隨用戶手勢動態變化,自如的VR看房,在我們APP里也引入了全景酒店實景體驗。在昂貴的VR設備消費者負擔不起的情況下,360度全境體驗正是VR在當今階段最普及的形態,雖然只是純粹的平面圖像,卻也一定程度上營造了沉浸式感受,而React360在靜態全景的基礎上引入了多種交互,這更加方便消費者瞭解需求,相信360全景的未來還能做得更多。

參考
https://facebook.github.io/react-360/


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • [20190515]熱備份模式與rman衝突.txt--//別人的系統做dg時打開熱備份模式,忘記關閉,做rman備份時報錯。做一個記錄。--//實際上也怪自己,實施時沒有講清楚。通過例子說明:1.環境:SCOTT@book> @ ver1PORT_STRING VERSION BANNER x86 ...
  • 在MS SQL Server 2016,已經支持JSON處理。 執行下麵代碼,將獲取ms sql server對象類型以及其說明: IF OBJECT_ID('tempdb.dbo.#json_type') IS NOT NULL DROP TABLE #json_type CREATE TABLE ...
  • MAX()/MIN() KEEP(DENSE_RANK LAST/FIRST) 函數 解釋: 1. max() 獲取最大值; 2.min() 獲取最小值; 3. keep 保持滿足括弧內條件的內容; 4.dense_rank 排序策略,連續排序,如果有兩個同一級別時,接下來是第二級別 ,例如1,2, ...
  • system_health會話概念 我們知道擴展事件(Extended Events)是從SQL Server 2008開始引入的。system_health會話是SQL Server預設包含的擴展事件會話。該會話在SQL Server資料庫引擎啟動時自動啟動,並且運行時不會對性能造成任何明顯影響。... ...
  • redis啟動報錯: [6644] 02 Apr 23:11:58.976 # Creating Server TCP listening socket *:6379: bind: No such file or directory 解決方案: 如下按順序輸入如下命令就可以連接成功 1. redis ...
  • RT3662結合了Rayink的雙頻 802.11n 系統單晶元,相容2T3RMAC,BB,2 4/5GHz射頻,高性能的500MHz MIPS74KcCPU核心,一個USB主機和一個USB OTG,兩個千兆位乙太網MAC,一個PCle主機/設備和一個PCI主機 /設備。RT3662採用Ralink ...
  • 來源:https://www.koofun.com/pro/kfpostsdetail?kfpostsid=33&cid= 本節將學習JavaScript語法的一些重要特性。 字元集 JavaScript使用Unicode字元集,因此幾乎允許所有字元、標點符號和符號。 大小寫敏感 JavaScrip ...
  • 經過前面幾次的學習,已經可以做下小功能,今天要實現的是修改用戶路由。 一、users_model.js 功能:定義用戶對象模型 二、users_controller.js 功能:為Express伺服器實現修改用戶路由 三、user.html 四、routes.js 功能:為Express伺服器實現處 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...