HTML5技術教程 前端開發之路—WebVR

来源:https://www.cnblogs.com/cldmxw/archive/2019/03/08/10493865.html
-Advertisement-
Play Games

2019,不管是不是VR元年,VR行業確實在這一年勢頭凶猛,VR設備跨越式發展,然而VR內容確相對滯後。強調獨占性的各大VR內容平臺,更是將開發商分割成了不同的陣營。 ...


        2019,不管是不是VR元年,VR行業確實在這一年勢頭凶猛,VR設備跨越式發展,然而VR內容確相對滯後。強調獨占性的各大VR內容平臺,更是將開發商分割成了不同的陣營。這項新的設備媒介同時驅動了瀏覽器開發商對Web進行虛擬現實的支持,WebVR的發展正集中於不可思議的視覺體驗以及創建線上虛擬現實環境的工具之上。

  WebVR 1.0 API 提議簡介

  Mozilla VR團隊正致力於在瀏覽器中支持線上創作及顯示VR內容,並已獲得重大突破。通過與Google Chrome團隊[Brandon Jones]的密切合作, Mozilla團隊發佈了WebVR API 1.0版本。

  本文主要討論的是本版本API的基本使用方式,這需要讀者能夠理解一些複雜的概念,例如:

  【數學中的矩陣】

  ( https://en.wikipedia.org/wiki/Matrix_%28mathematics%29 )

  此外,您也可以通過閱讀 [A-Frame]( https://aframe.io/ )

  或者

  [WebVR boilerplate]( https://github.com/borismus/webvr-boilerplate/ )以快速入門WebVR。

  如何開始實施WebVR

  想要從現在開始嗎?目前,開發者可以通過使用Brandon Jone的

  [實驗版Chromium]

  ( https://drive.google.com/a/mozilla.com/folderview?id=0BzudLt22BqGRbW9WTHMtOWMzNjQ&usp=sharing#list )來做一些驗證性的實驗。

  [three.js] (http://threejs.org/ )

  [WebVR Polyfill]( https://github.com/borismus/webvr-polyfill/ )

  VR體驗的構成要素

  讓我們瞭解一下VR體驗的關鍵構成要素:

  1. 我們所渲染的虛擬現實顯示的內容。

  2. 用戶姿態,頭盔在空間中的位置及方向。

  3. 眼部參數定義的視距立體間隔或立體視覺(stereo separation)以及視野範圍。

  現在讓我們看一下使內容呈現在VR頭盔中的執行順序:

  1. 使用`navigator.getVRDisplays()` 來檢索VR設備。

  2. 創建一個canvas元素來渲染顯示內容。

  3. 在canvas元素中,使用`VRDisplay.requestPresent()`。

  4. 創建一個VR設備特定的動畫迴圈,以執行內容渲染。

  1)使用`VRDisplay.getPose()` 更新用戶動作。

  2)進行計算和渲染。

  3)使用 `VRDisplay.submitFrame()` 來告訴合成器,canvas元素準備好在VR設備顯示的時間。

  下述部分描述了每一個行為的具體細節。

  關於VR顯示設備

  VR顯示設備對於顯示有著許多非常特殊的需求,比如:

  [幀率(frame rate)]( https://en.wikipedia.org/wiki/Frame_rate ),

  [視野範圍(field of view)]

  ( https://en.wikipedia.org/wiki/Field_of_view ),以及從標準桌面顯示中,拆分獨立處理的內容表現方式。

  檢索VR顯示設備

  為了使得使用瀏覽器進行VR設備檢索成為可能,可以使用`navigator.getVRDisplays()`方法,該方法返回一個由包含一系列`VRDisplay`對象的數組構成的約定(Promise):

  …

  navigator.getVRDisplays().then(function (displays) {

  if (!displays.length) {

  // 支持WebVR,沒有發現任何VR顯示設備。

  return;

  }

  //處理 VRDisplay 對象 (作為全局變數)。

  vrDisplay = displays.length[0];

  }).catch(function (err) {

  console.error('Could not get VRDisplays', err.stack);

  });

  …

  註意:

  * 您必須在對VR設備進行檢索之前,保證您的VR頭盔已經接入並開啟。

  * 如果您沒有VR頭盔,你可以通過將`about:config`打開以及設置`dom.vr.cardboard.enabled`的值為`true`,來進行模擬模擬。

  * [Firefox Nightly for Android]( https://nightly.mozilla.org/#Android )的用戶或者 [Firefox for iOS]( https://www.mozilla.org/en-US/firefox/ios/ )的用戶可以通過使用

  [Google Cardboard]( https://www.google.com/get/cardboard/ )進行CardBorad設備的檢索。

  創建渲染對象

  為確定渲染對象的大小(比如,你的canvas大小),請創建一個能夠覆蓋雙眼視野範圍的渲染對象。為確定每隻眼睛的視野範圍(以像素為單位),參考以下代碼:

  …

  // 使用 'left'(左) 或 'right'(右).

  var eyeParameter = vrDisplay.getEyeParameters('left');

  var width = eyeParameter.renderWidth;

  var height = eyeParameter.renderHeight;

  …

  將內容顯示在VR頭盔中

  為了讓內容呈現在頭盔中,你需要使用`VRDisplay.requestPresent()`方法,該方法使用了WebGL元素作為參數,表示要顯示的可視面。

  為了防止API被冗餘調用,瀏覽器需要一個用戶初始化事件,確保用戶是第一次進入VR模式。換句話說,用戶必須選擇開啟VR,所以我們將“進入VR”設定成一個按鈕作為`click`事件觸發。

  …

  // 選擇 WebGL canvas元素。

  var webglCanvas = document.querySelector('#webglcanvas');

  var enterVRBtn = document.querySelector('#entervr');

  enterVRBtn.addEventListener('click', function () {

  // 將當前的WebGL canvas設置為VR顯示。

  vrDisplay.requestPresent({source: webglCanvas});

  });

  // 退出當前顯示。

  vrDisplay.exitPresent();

  …

  設備特定的 `requestAnimationFrame`

  既然我們建立了渲染對象,以及必要的渲染所需參數使得內容可以在頭盔中正確地顯示出來,我們現在可以創建一個場景的迴圈渲染。

  我們希望通過使用回調方法`VRDisplay.requestAnimationFrame`以此來優化VR顯示設備的刷新率:

  …

  var id = vrDisplay.requestAnimationFrame(onAnimationFrame);

  function onAnimationFrame () {

  // 迴圈渲染。

  id = vrDisplay.requestAnimationFrame(onAnimationFrame);

  }

  // 結束渲染迴圈。

  vrDisplay.cancelRequestAnimationFrame(id);

  …

  這與你所熟悉的標準回調函數 `window.requestAnimationFrame()`的用法是一致的。我們使用這個回調函數以適應顯示內容中動作的位置和方向的不斷更新,並對VR顯示進行渲染。

  從VR顯示中捕獲動作姿態信息

  我們需要通過使用`VRDisplay.getPose()`方法來捕獲頭盔的位置和方向:

  …

  var pose = vrDisplay.getPose();

  // 返回一個四元組。

  var orientation = pose.orientation;

  // 返回一個三維絕對位置向量。

  var position = pose.position;

  …

  請註意:

  * 如果無法確定位置及方向,這些信息將返回`null`。

  更多詳情請參考 [VRStageCapabilities]

  ( https://mozvr.github.io/webvr-spec/#interface-vrdisplaycapabilities )以及 [VRPose]( https://mozvr.github.io/webvr-spec/#interface-vrpose )。

  投射場景到VR顯示

  為了使頭盔中的場景準確的進行立體渲染,我們需要提供一些眼部參數,例如眼部偏移量(基於 [瞳距(interpupillary distance or IPD)]

  ( https://en.wikipedia.org/wiki/Interpupillary_distance ),以及視野範圍(FOV)。

  …

  // 用左右眼參數之一作為參數傳入.

  var eyeParameters = vrDisplay.getEyeParameters('left');

  // 根據VRPose翻譯完世界坐標之後,繼續減去眼部偏移量進行變換

  var eyeOffset = eyeParameters.offset;

  // 使用映射矩陣進行映射。

  var eyeMatrix = makeProjectionMatrix(vrDisplay, eyeParameters);

  // 將eyeMatrix顯示到你的view中。

  …

  /**

  * 生成映射矩陣

  * @param {object} display - VRDisplay

  * @param {number} eye - VREyeParameters

  * @returns {Float32Array} 4×4 映射矩陣

  */

  function makeProjectionMatrix (display, eye) {

  var d2r = Math.PI / 180.0;

  var upTan = Math.tan(eye.fieldOfView.upDegrees * d2r);

  var downTan = Math.tan(eye.fieldOfView.leftDegrees * d2r);

  var rightTan = Math.tan(eye.fieldOfView.rightDegrees * d2r);

  var leftTan = Math.tan(eye.fieldOfView.leftDegrees * d2r);

  var xScale = 2.0 / (leftTan + rightTan);

  var yScale = 2.0 / (upTan + downTan);

  var out = new Float32Array(16);

  out[0] = xScale;

  out[1] = 0.0;

  out[2] = 0.0;

  out[3] = 0.0;

  out[4] = 0.0;

  out[5] = yScale;

  out[6] = 0.0;

  out[7] = 0.0;

  out[8] = -((leftTan - rightTan) * xScale * 0.5);

  out[9] = (upTan - downTan) * yScale * 0.5;

  out[10] = -(display.depthNear + display.depthFar) / (display.depthFar - display.depthNear);

  out[12] = 0.0;

  out[13] = 0.0;

  out[14] = -(2.0 * display.depthFar * display.depthNear) / (display.depthFar - display.depthNear);

  out[15] = 0.0;

  return out;

  }

  …

  向頭盔提交幀

  VR對於降低用戶運動產生的不連續性做了一定的優化。這對舒服的體驗(不使人眩暈)至關重要。直接使用`VRDisplay.getPose()` 和 `VRDisplay.submitFrame()`方法來對這一現象進行控制:

  …

  // 渲染和計算不依賴於姿態。

  // ...

  var pose = vrDisplay.getPose();

  // 在此將你生成的眼部矩陣適配到view中。

  // 儘量在此處減少操作數量。

  // ...

  vrDisplay.submitFrame(pose);

  //在提交之後對幀作出的任何操作不會給VR帶來延遲。此時可以渲染其他的view。

  // ...

  …

  一般而言,正確的姿勢是,儘可能早的調用`VRDisplay.submitFrame()`方法,並儘可能晚地調用`VRDisplay.getPose()`方法。

  ### 示例Demo

  https://toji.github.io/webvr-samples/

 


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

-Advertisement-
Play Games
更多相關文章
  • 在android中,如何將html代碼轉換為text,然後顯示在textview中呢,有一個簡單直接的方法: 然而用的時候卻發現html裡面的圖片沒法被被解析出來,別慌,Html還有一個方法: 其中,我們可以自定義imageGetter,這個對象是用於解析html中的圖片。 最終調用: textVi ...
  • 概述 UITextView可滾動的多行文本區域 UITextView支持使用自定義樣式信息顯示文本,並支持文本編輯。您通常使用文本視圖來顯示多行文本,例如在顯示大型文本文檔的正文時。 UITextView繼承於UIScrollView 屬性和方法 初始化方法 UITextView *textView ...
  • ...
  • 一、簡述 在iOS開發過程中,頁面跳轉時在頁面之間進行數據傳遞是很常見的事情,我們稱這個過程為頁面傳值。頁面跳轉過程中,從主頁面跳轉到子頁面的數據傳遞稱之為正向傳值;反之,從子頁面返回主頁面時的數據傳遞稱之為反向傳值。 目前我所瞭解和掌握的傳值方式有: 二、頁面傳值的詳解 2.0 準備工作 為了實現 ...
  • 馬甲包的字面意思給產品穿馬甲,但是我認為馬甲包更像是產品的一種分身,一種和產品一樣擁有靈魂,擁有肉身的一種分身。它能為產品帶來同樣的功能效果。 一、什麼是馬甲包通過技術手段,多次上架同一款產品的方法。馬甲包和主產品包擁有同樣的內容和功能,除了icon和應用名稱不能完全一致,其他基本一致。 二、為什麼 ...
  • 在Xcode里下載模擬器,速度實在是太慢了。點擊下載,卡住十幾分鐘才開始下載,並且龜速進行。解決方案:獲取模擬器下載地址,自己選擇下載器進行下載。找到下載鏈接打開 Console.app(蘋果電腦自帶的一個程式),點擊“Clear”按鈕來清空log。打開 Xcode - Preferences - ... ...
  • addGestureRecognizer(_:) 一個手勢對象只綁定一個view// 只有最後一個imgv有點擊事件 let tap = UITapGestureRecognizer(target: self, action: #selector(selectedItem(_:))) for img... ...
  • Javascript中有六種數據類型 1、undefined:這個值未定義 2、boolean:這個值是布爾值 3、number:這個值是數值 4、function:這個值是函數 5、object:這個值是對象或者null,數組也可以(var e=[.......]) 6、string:這個值是字元 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...