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
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...