摘要:通過(guò)佩戴的分離式頭顯瀏覽連接在主機(jī)端的網(wǎng)頁(yè),現(xiàn)支持的瀏覽器主要是火狐的和設(shè)置的谷歌。的概念大概就如此,這次我們將采用的方式來(lái)測(cè)試我們的場(chǎng)景,現(xiàn)在踏上我們的開發(fā)之旅。
WebVR即web + VR的體驗(yàn)方式,我們可以戴著頭顯享受沉浸式的網(wǎng)頁(yè),新的API標(biāo)準(zhǔn)讓我們可以使用js語(yǔ)言來(lái)開發(fā)。本文將介紹如何快速開發(fā)一個(gè)WebVR網(wǎng)頁(yè),在此之前,我們有必要了解WebVR的體驗(yàn)方式。
WebVR體驗(yàn)?zāi)J?/b>
WebVR的體驗(yàn)方式可以分為VR模式和裸眼模式
1.Mobile VR
如使用cardboard眼鏡來(lái)體驗(yàn)手機(jī)瀏覽器的webVR網(wǎng)頁(yè),瀏覽器將根據(jù)水平陀螺儀的參數(shù)來(lái)獲取用戶的頭部?jī)A斜和轉(zhuǎn)動(dòng)的朝向,并告知頁(yè)面需要渲染哪一個(gè)朝向的場(chǎng)景。
2.PC VR
通過(guò)佩戴Oculus Rift的分離式頭顯瀏覽連接在PC主機(jī)端的網(wǎng)頁(yè),現(xiàn)支持WebVR API的瀏覽器主要是火狐的?Firefox Nightly和設(shè)置VR enabled的谷歌chrome beta。
裸眼模式除了VR模式下的體驗(yàn)方式,這里還考慮了裸眼下的體驗(yàn)瀏覽網(wǎng)頁(yè)的方式,在PC端如果探測(cè)的用戶選擇進(jìn)入VR模式,應(yīng)讓用戶可以使用鼠標(biāo)拖拽場(chǎng)景,而在智能手機(jī)上則應(yīng)讓用戶可以使用touchmove或旋轉(zhuǎn)傾斜手機(jī)的方式來(lái)改變場(chǎng)景視角。
WebVR的概念大概就如此,這次我們將采用cardboard + mobile的方式來(lái)測(cè)試我們的WebVR場(chǎng)景,現(xiàn)在踏上我們的開發(fā)之旅。
測(cè)試工具:智能手機(jī) + cardboard式頭顯 + chrome beta 60+(需開啟WebVR選項(xiàng))
如果你練就了裸眼就能將手機(jī)雙屏畫面看成單屏的能力也可以省下頭顯。
技術(shù)和框架:three.js for WebGL
Three.js是構(gòu)建3d場(chǎng)景的框架,它封裝了WebGL函數(shù),簡(jiǎn)化了創(chuàng)建場(chǎng)景的代碼成本,利用three.js我們可以更優(yōu)雅地創(chuàng)建出三維場(chǎng)景和三維動(dòng)畫,這里我使用的是0.86版本。
如果想了解純WebGL開發(fā)WebVR應(yīng)用以及WebVR具體環(huán)境配置,可以參考 webvr教程--深度剖析。
需要引入的js插件:
1.three.min.js
2.webvr-polyfill.js 由于WebVR API還沒被各大主流瀏覽器支持,因此需要引入它來(lái)解決兼容性問(wèn)題。
首先我們創(chuàng)建一個(gè)HTML文件
webVR-helloworld
接下來(lái)編寫js腳本,開始創(chuàng)建我們的3d場(chǎng)景。
1.創(chuàng)建場(chǎng)景Three.js中的scene場(chǎng)景是繪制我們3d對(duì)象的整個(gè)容器
var scene = new THREE.Scene();2.添加相機(jī)
Three.js中的camera相機(jī)代表用戶的眼睛,我們通過(guò)設(shè)置FOV確定視野范圍,
//定義一個(gè)60°的視角,視線范圍在1到1000的透視相機(jī) var camera = new THREE. new THREE.PerspectiveCamera(60,window.innerWidth/window.innerHeight,1,1000); scene.add(camera);3.添加渲染器
Three.js的渲染器用來(lái)渲染camera所看到的畫面
//初始化渲染器 antialias參數(shù)為ture表示開啟抗鋸齒策略 var renderer = new THREE.WebGLRenderer({ antialias: true } ); //設(shè)置渲染器渲染尺寸 renderer.setSize(window.innerWidth,window.innerHeight); //設(shè)置渲染背景為白色 renderer.setClearColor(0xeeeeee); //將渲染場(chǎng)景的canvas放入body標(biāo)簽里 document.body.appendChild(renderer.domElement);
// 創(chuàng)建立方體 var geometry = new THREE.CubeGeometry( 10,10,10); var material = new THREE.MeshLambertMaterial( { color: 0xef6500,needsUpdate: true,opacity:1,transparent:true} ); var cube = new THREE.Mesh( geometry, material ); cube.position.set(0,100,-50); cube.rotation.set(Math.PI/6,Math.PI/4,0); scene.add(cube);5.啟動(dòng)動(dòng)畫
動(dòng)畫渲染的原理:渲染器的持續(xù)調(diào)用繪制方法,方法里動(dòng)態(tài)改變物體的屬性。
舊版的three.js需要手動(dòng)調(diào)用requestAnimationFrame()方法遞歸的方式來(lái)渲染動(dòng)畫,新版three.js已經(jīng)封裝了該屬性,因此只需要通過(guò)渲染器renderer.animate(callback)。
function update() { //讓立方體旋轉(zhuǎn) cube.rotation.y += 0.01; //渲染器渲染場(chǎng)景,等同于給相機(jī)按下快門 renderer.render(scene, camera); } renderer.animate(update);//啟動(dòng)動(dòng)畫
至此,我們已經(jīng)繪制了一個(gè)簡(jiǎn)單的3d場(chǎng)景并且讓它動(dòng)了起來(lái),接下來(lái),我們需要讓我們的場(chǎng)景可以支持WebVR模式。
WebVR場(chǎng)景開發(fā)WebVR網(wǎng)頁(yè)開發(fā)的基本原理是通過(guò)WebVR API獲取VR動(dòng)態(tài)數(shù)據(jù)(VR Display frameData),渲染器根據(jù)VR數(shù)據(jù)來(lái)分別繪制左右屏場(chǎng)景,具體步驟如下:
使用navigator.getVRDisplays獲取vr設(shè)備示例
vrdisplay是vr設(shè)備的實(shí)例,我們需要將它傳給當(dāng)前運(yùn)行的renderer渲染器。
function initVR(renderer) { renderer.vr.enabled = true; navigator.getVRDisplays().then( function(display) { renderer.vr.setDevice(display[0]); const button = document.querySelector(".vr-btn"); VRbutton(display[0],renderer,button,function() { button.textContent = "退出VR"; },function() { button.textContent = "進(jìn)入VR"; }); }).catch(err => console.warn(err)); }
這里需要通過(guò)按鈕來(lái)控制當(dāng)前的渲染模式:
當(dāng)點(diǎn)擊按鈕時(shí),根據(jù)display.isPresenting判斷當(dāng)前是否是使用vr設(shè)備下進(jìn)行渲染,如果false,進(jìn)入2,否則true進(jìn)入3
當(dāng)前非VR模式,點(diǎn)擊按鈕進(jìn)入VR模式,此時(shí)調(diào)用display.requestPresent(),display.isPresenting被設(shè)置為true,觸發(fā)window的vrdisplaypresentchange事件
當(dāng)前為VR模式,點(diǎn)擊按鈕退出模式,此時(shí)調(diào)用display.exitPresent(),display.isPresenting被設(shè)置為false,觸發(fā)window的vrdisplaypresentchange事件
/** VR按鈕控制 * @param {VRDisplay} display VRDisplay實(shí)例 * @param {THREE.WebGLRenderer} renderer 渲染器 * @param {HTMLElement} button VR控制按鈕 * @param {Function} enterVR 點(diǎn)擊進(jìn)入VR模式時(shí)回調(diào) * @param {Function} exitVR 點(diǎn)擊退出VR模式時(shí)回調(diào) **/ function VRbutton(display,renderer,button,enterVR,exitVR) { if ( display ) { button.addEventListener("click", function() { // 點(diǎn)擊vr按鈕控制`isPresenting`狀態(tài) display.isPresenting ? display.exitPresent() : display.requestPresent( [ { source: renderer.domElement } ] ); }); window.addEventListener( "vrdisplaypresentchange", function() { // 是否處于vr體驗(yàn)?zāi)J街?,是則觸發(fā)enterVR,否則觸發(fā)exitVR display.isPresenting ? enterVR() : exitVR(); }, false ); } else { // 找不到vr設(shè)備實(shí)例,則移除按鈕 button.remove(); } }
我們可以在vrdisplaypresentchange事件中根據(jù)isPresenting的值來(lái)改變按鈕的UI,而three.js將根據(jù)isPresenting的值來(lái)決定是常規(guī)渲染還是vr模式渲染,在vr模式下,three.js將創(chuàng)建兩個(gè)camera進(jìn)行渲染。
代碼優(yōu)化最后,將WebVR應(yīng)用寫成ES6 class,后面開發(fā)流程將按如下圖結(jié)構(gòu)來(lái)規(guī)范代碼:
第一步,構(gòu)造函數(shù)先初始化VR場(chǎng)景、相機(jī)和渲染器;第二步,在渲染之前調(diào)用start方法,在start方法里我們?yōu)閳?chǎng)景創(chuàng)建3d物體;最后,調(diào)起renderer.animate(this.update)開啟動(dòng)畫渲染,update方法里我們可動(dòng)態(tài)操作物體屬性,具體代碼如下:
class WebVRApp { constructor() { // 初始化場(chǎng)景 this.scene = new THREE.Scene(); // 初始化相機(jī) this.camera = new THREE.PerspectiveCamera(60,window.innerWidth/window.innerHeight,0.1,1000); this.scene.add(this.camera); // 初始化渲染器 this.renderer = new THREE.WebGLRenderer({ antialias: true } ); this.renderer.setSize(window.innerWidth,window.innerHeight); this.renderer.setClearColor(0x519EcB); this.renderer.setPixelRatio(window.devicePixelRatio); document.querySelector(".main-page").appendChild(this.renderer.domElement); this.clock = new THREE.Clock(); // VR初始化 this.initVR(); // 往場(chǎng)景添加3d物體 this.start(); // 窗口大小調(diào)整監(jiān)聽 window.addEventListener( "resize", this.resize.bind(this), false ); // 渲染動(dòng)畫 this.renderer.animate(this.update.bind(this)); } // 創(chuàng)建3d物體 start() { const {scene,camera} = this; // 創(chuàng)建光線 scene.add(new THREE.AmbientLight(0xFFFFFF)); this.addLight(); // 創(chuàng)建地面 this.addGround(1000,1000); // 創(chuàng)建立方體 this.addCube(2,2,2, 2,-1,-3); } // VR模式初始化 initVR() { const {renderer} = this; renderer.vr.enabled = true; // 獲取VRDisplay實(shí)例 navigator.getVRDisplays().then( display => { // 將display實(shí)例傳給renderer渲染器 renderer.vr.setDevice(display[0]); const button = document.querySelector(".vr-btn"); VRButton.init(display[0],renderer,button,() => button.textContent = "退出VR",() => button.textContent = "進(jìn)入VR"); }).catch(err => console.warn(err)); } // 窗口調(diào)整監(jiān)聽 resize() { const {camera,renderer} = this; // 窗口調(diào)整重新調(diào)整渲染器 camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); renderer.setSize(window.innerWidth, window.innerHeight); } addCube(width=2,height=2,depth=2, posX,posY,posZ) { const {scene} = this; // 創(chuàng)建立方體 const geometry = new THREE.CubeGeometry(width,height,depth); const material = new THREE.MeshLambertMaterial({ color: 0xef6500, needsUpdate: true, opacity:1, transparent:true }); const cube = new THREE.Mesh( geometry, material ); cube.position.set({ x: posX, y: posY, z: posZ }); this.cube = cube; scene.add(cube); } addGround(width,height) { const {scene} = this; // 創(chuàng)建地平面 const geometry = new THREE.PlaneBufferGeometry( width, height ); const material = new THREE.MeshPhongMaterial( { color: 0xaaaaaa } ); const ground = new THREE.Mesh( geometry, material ); ground.rotation.x = - Math.PI / 2; ground.position.y = -10; scene.add(cube); } // 動(dòng)畫更新 update() { const {scene,camera,renderer,clock} = this; const delta = clock.getDelta() * 60; // 啟動(dòng)渲染 this.cube.rotation.y += 0.1 * delta; renderer.render(scene, camera); } } new WebVRApp();
完整代碼:github.com/YoneChen/WebVR-helloworld。
結(jié)語(yǔ)目前,國(guó)外的谷歌、火狐、Facebook和國(guó)內(nèi)百度已推出支持WebVR瀏覽器的版本,微軟也宣布將推出自己的VR瀏覽器,隨著后期5g網(wǎng)絡(luò)極速時(shí)代的到來(lái)以及HMD頭顯的價(jià)格和平臺(tái)的成熟,WebVR的體驗(yàn)方式將是革命性的,用戶通過(guò)WebVR瀏覽網(wǎng)上商店,線上教學(xué)可進(jìn)行“面對(duì)面”師生交流等,基于這種種應(yīng)用場(chǎng)景,我們可以找到一個(gè)更好的動(dòng)力去學(xué)習(xí)WebVR。
參考鏈接responisve WebVR: 探討WebVR在不同頭顯(HMD)的適配方案
MolizaVR example: 火狐WebVR示例
webvr-boilerplate: A starting point for web-based VR experiences that work on all VR headsets.
how to build webvr: How to Build VR on the Web Today
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/82306.html
摘要:通過(guò)閱讀本文,你將了解到的優(yōu)勢(shì)即將燃爆的領(lǐng)域以及程序員在快速發(fā)展的產(chǎn)業(yè)中所需關(guān)注的技術(shù)。在沒有堵車醉駕疲勞駕駛女性乘車等安全問(wèn)題的未來(lái),這將是極大的福利。 導(dǎo)讀:本文共2894字,預(yù)計(jì)閱讀時(shí)間為9分鐘。通過(guò)閱讀本文,你將了解到5G的優(yōu)勢(shì)、即將燃爆的領(lǐng)域以及程序員在快速發(fā)展的5G產(chǎn)業(yè)中所需關(guān)注的技術(shù)。 5G時(shí)代已經(jīng)來(lái)臨 隨著中美5G主導(dǎo)權(quán)之戰(zhàn)的持續(xù)發(fā)酵,5G時(shí)代正式拉開了序幕。最近,5G...
摘要:通過(guò)閱讀本文,你將了解到的優(yōu)勢(shì)即將燃爆的領(lǐng)域以及程序員在快速發(fā)展的產(chǎn)業(yè)中所需關(guān)注的技術(shù)。在沒有堵車醉駕疲勞駕駛女性乘車等安全問(wèn)題的未來(lái),這將是極大的福利。 導(dǎo)讀:本文共2894字,預(yù)計(jì)閱讀時(shí)間為9分鐘。通過(guò)閱讀本文,你將了解到5G的優(yōu)勢(shì)、即將燃爆的領(lǐng)域以及程序員在快速發(fā)展的5G產(chǎn)業(yè)中所需關(guān)注的技術(shù)。 5G時(shí)代已經(jīng)來(lái)臨 隨著中美5G主導(dǎo)權(quán)之戰(zhàn)的持續(xù)發(fā)酵,5G時(shí)代正式拉開了序幕。最近,5G...
摘要:去年月,阿里云宣布將設(shè)立阿里云廣東研發(fā)中心,招募名云計(jì)算和人工智能工程師,推動(dòng)前沿技術(shù)與廣東產(chǎn)業(yè)融合。吳維剛表示,人工智能與云計(jì)算,兩者不是同一事物,但是相互發(fā)展。近年來(lái),隨著互聯(lián)網(wǎng)和移動(dòng)互聯(lián)網(wǎng)的蓬勃發(fā)展,大數(shù)據(jù)、云計(jì)算、人工智能、物聯(lián)網(wǎng)等新技術(shù)也迎來(lái)了廣闊的發(fā)展空間。去年,阿里云工業(yè)互聯(lián)網(wǎng)全國(guó)總部正式在廣州揭牌成立,阿里云將聯(lián)合廣東本地合作伙伴,共同打造服務(wù)全國(guó)的工業(yè)大腦。去年9月,華為與...
摘要:去年月,華為與白云區(qū)簽署云計(jì)算產(chǎn)業(yè)戰(zhàn)略合作協(xié)議,將協(xié)同打造千億元級(jí)新一代信息產(chǎn)業(yè)集群。融入智慧大腦人工智能是火箭云計(jì)算是引擎業(yè)內(nèi),大家將人工智能大數(shù)據(jù)以及云計(jì)算稱為鐵三角關(guān)系。吳維剛表示,人工智能與云計(jì)算,兩者不是同一事物,但是相互發(fā)展。近年來(lái),隨著互聯(lián)網(wǎng)和移動(dòng)互聯(lián)網(wǎng)的蓬勃發(fā)展,大數(shù)據(jù)、云計(jì)算、人工智能、物聯(lián)網(wǎng)等新技術(shù)也迎來(lái)了廣闊的發(fā)展空間。去年,阿里云工業(yè)互聯(lián)網(wǎng)全國(guó)總部正式在廣州揭牌成立,...
摘要:如果佛羅倫薩像長(zhǎng)驅(qū)直入,那么即便內(nèi)陸的數(shù)據(jù)中心也同樣令人擔(dān)憂。另外,油罐車無(wú)法為發(fā)電機(jī)輸送柴油燃料,美國(guó)境內(nèi)有幾個(gè)數(shù)據(jù)中心失去了電力。其他數(shù)據(jù)中心不得不依靠備用電力長(zhǎng)達(dá)一周。颶風(fēng)來(lái)襲。美國(guó)所有公共云服務(wù)提供商和美國(guó)大型技術(shù)公司都未雨綢繆,進(jìn)行各種布局,以確保其建筑物足夠堅(jiān)固以應(yīng)對(duì)颶風(fēng)構(gòu)成的威脅。數(shù)據(jù)中心正在為名為佛羅倫薩的颶風(fēng)做好準(zhǔn)備,因?yàn)樗挥谀峡_來(lái)納州和北卡羅來(lái)納州,并在未來(lái)幾天向弗吉...
閱讀 3695·2021-10-09 09:44
閱讀 3400·2021-09-22 15:29
閱讀 3158·2019-08-30 15:54
閱讀 3030·2019-08-29 16:19
閱讀 2157·2019-08-29 12:50
閱讀 602·2019-08-26 14:04
閱讀 1709·2019-08-23 18:39
閱讀 1359·2019-08-23 17:59