成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

VR大潮來(lái)襲 ---前端開發(fā)能做些什么

mikyou / 2603人閱讀

摘要:通過(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模式和裸眼模式

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ā)之旅。

準(zhǔn)備工作

測(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)題。

3D場(chǎng)景構(gòu)建

首先我們創(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);
4.添加一個(gè)立方體網(wǎng)格
// 創(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ān)文章

  • 5G浪潮來(lái)襲,程序員在風(fēng)口中有何機(jī)遇

    摘要:通過(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...

    NikoManiac 評(píng)論0 收藏0
  • 5G浪潮來(lái)襲,程序員在風(fēng)口中有何機(jī)遇

    摘要:通過(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...

    idealcn 評(píng)論0 收藏0
  • 人工智能融入“云”端

    摘要:去年月,阿里云宣布將設(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月,華為與...

    yacheng 評(píng)論0 收藏0
  • 人工智能融入“云”端:人工智能是火箭,云計(jì)算是引擎

    摘要:去年月,華為與白云區(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ó)總部正式在廣州揭牌成立,...

    騫諱護(hù) 評(píng)論0 收藏0
  • 颶風(fēng)來(lái)襲,數(shù)據(jù)中心企業(yè)如何躲過(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)幾天向弗吉...

    不知名網(wǎng)友 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

mikyou

|高級(jí)講師

TA的文章

閱讀更多
最新活動(dòng)
閱讀需要支付1元查看
<