時(shí)間:2022-08-30 15:09:01 | 來源:網(wǎng)站運(yùn)營(yíng)
時(shí)間:2022-08-30 15:09:01 來源:網(wǎng)站運(yùn)營(yíng)
WebVR即web + VR的體驗(yàn)方式,本文介紹如何開發(fā)一個(gè)WebVR網(wǎng)頁,在此之前,我們有必要了解WebVR的體驗(yàn)方式。測(cè)試工具:智能手機(jī) + cardboard式頭顯 + chrome beta 60+(需開啟WebVR選項(xiàng))如果你練就了裸眼就能將手機(jī)雙屏畫面看成單屏的能力也可以省下頭顯。
技術(shù)和框架:three.js for WebGLThree.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
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0, shrink-to-fit=no"> <title>webVR-helloworld</title> <style type="text/css"> * { margin: 0; padding: 0; } html,body { height: 100%; overflow: hidden; } </style></head><body></body><script src="./vendor/three.min.js"></script><script src="./vendor/webvr-polyfill.js"></script><script></script></html>
接下來編寫js腳本,開始創(chuàng)建我們的3d場(chǎng)景。var scene = new THREE.Scene();
//定義一個(gè)60°的視角,視線范圍在1到1000的透視相機(jī)var camera = new THREE. new THREE.PerspectiveCamera(60,window.innerWidth/window.innerHeight,1,1000);scene.add(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);
function update() { //讓立方體旋轉(zhuǎn) cube.rotation.y += 0.01; //渲染器渲染場(chǎng)景,等同于給相機(jī)按下快門 renderer.render(scene, camera);}renderer.animate(update);//啟動(dòng)動(dòng)畫
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));}
這里需要通過按鈕控制當(dāng)前的渲染模式邏輯如下:/** 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街校莿t觸發(fā)enterVR,否則觸發(fā)exitVR display.isPresenting ? enterVR() : exitVR(); }, false ); } else { // 找不到vr設(shè)備實(shí)例,則移除按鈕 button.remove(); }}
我們可以在vrdisplaypresentchange事件中根據(jù)isPresenting的值來改變按鈕的UI,而three.js將根據(jù)isPresenting的值來決定是常規(guī)渲染還是vr模式渲染,在vr模式下,three.js將創(chuàng)建兩個(gè)camera進(jìn)行渲染。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)建光線、地面等 ... // 創(chuàng)建立方體 const geometry = new THREE.CubeGeometry(2, 2, 2); const material = new THREE.MeshLambertMaterial({ color: 0xef6500, }); this.cube = new THREE.Mesh( geometry, material ); this.cube.position.set({ x: 0, y: 0, z: -4 }); scene.add(this.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); } // 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); }}new WebVRApp();
客戶&案例
營(yíng)銷資訊
關(guān)于我們
客戶&案例
營(yíng)銷資訊
關(guān)于我們
微信公眾號(hào)
版權(quán)所有? 億企邦 1997-2022 保留一切法律許可權(quán)利。