做有态度的前端团队

网易FEG前端团队

吱吱说VR,你怕了吗?

首先,看下demo效果,扫一下下面的二维码:
下载.png

主要利用浏览器的deviceorientation事件监视设备朝向,记录下其受地心引力作用下而在方向上产生变化的数据,然后使用DeviceOrientationControls.js(一个three.js的插件)让摄像头根据设备的移动进行调整,相当于模拟人看向物体的某个方向,犹如人的视线一样。最后,结合three.js来构建一个3d世界。

1. 画一个会动的太阳

引用three.js, 建立3个要素:场景(scene)、相机(camera)和渲染器(renderer)。有了这三样东西,才能将物体渲染到网页中,然后再画一个太阳。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
    var canvas = document.querySelector('#main-canvas');
    var scene = new THREE.Scene();
    var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1 ,2000);
 
scene.add(camera);
 
    //画太阳
    var initPlanet = function(name, revolutionSpeed, color, distance, volume, map) {
    var material;
 
    material = new THREE.MeshLambertMaterial({
        emissive: 0xdd4422,  //发光
        map: THREE.ImageUtils.loadTexture(__uri('../../img/sun.jpg')) //太阳的皮肤
    });
 
    //SphereGeometry用来在三维空间内创建一个球体对象.
    var mesh = new THREE.Mesh( new THREE.SphereGeometry( volume, 50,50 ), material);
    mesh.position.x = -distance;
    mesh.receiveShadow = true;
    mesh.castShadow = true;
 
    scene.add(mesh);
};
    initPlanet();
 
    //由于是会动的,所以调用requestAnimationFrame函数
    (function render(timestamp) {
    requestAnimationFrame(render);
    //太阳自转
    stars.Sun.Mesh.rotation.y = (stars.Sun.Mesh.rotation.y == 2*Math.PI ? 0.0008*Math.PI : stars.Sun.Mesh.rotation.y+0.0008*Math.PI);
    renderer.render(scene, camera);
}());

就这样简单画出了一个太阳。扫二维码看效果。
下载 (1).png

2. 构建一个太阳系

为了效果好看一点,顺便把其他行星也画上去,实现原理跟太阳的一样。接着就让各行星围绕着太阳转啊转。

1
2
3
4
5
6
7
8
    //RingGeometry用来在三维空间内创建一个二维圆环面对象.
    //轨道, 以太阳为中心的运动轨道
var track = new THREE.Mesh( new THREE.RingGeometry(distance - 0.2, distance + 0.2, 100, 1),
        new THREE.MeshBasicMaterial( { color: 0xffffff,transparent: true, opacity: 0.1, side: THREE.DoubleSide } )
    );
track.rotation.x = - Math.PI / 2;
 
scene.add(track);

再画点星星点缀一下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
    //buffer做星星
var bufferGeometry = new THREE.BufferGeometry();
    var gap = 1000; // 定义星星的最近出现位置
 
for ( var i = 0; i < positions.length; i += 3 ) {
    // positions
 
    //-2gap < x < 2gap
    var x = ( Math.random() * gap *2 )* (Math.random()<.5? -1 : 1);
    var y = ( Math.random() * gap *2 )* (Math.random()<.5? -1 : 1);
    var z = ( Math.random() * gap *2 )* (Math.random()<.5? -1 : 1);
            /*找出x,y,z中绝对值最大的一个数*/
    var biggest = Math.abs(x) > Math.abs(y) ? (Math.abs(x) > Math.abs(z) ? 'x' : 'z') : (Math.abs(y) > Math.abs(z) ? 'y' : 'z');
 
    var pos = { x: x, y: y, z: z};
 
    //如果最大值比n要小(因为要在一个距离之外才出现星星)则赋值为n(-n)
    if(Math.abs(pos[biggest]) < gap) pos[biggest] = pos[biggest] < 0 ? -gap : gap;
 
    x = pos['x'];
    y = pos['y'];
    z = pos['z'];
 
    positions[ i ]     = x;
    positions[ i + 1 ] = y;
    positions[ i + 2 ] = z;
            //70%星星有颜色
    var hasColor = Math.random() > 0.3;
    var vx, vy, vz;
 
    if(hasColor){
        vx = (Math.random()+1) / 2 ;
        vy = (Math.random()+1) / 2 ;
        vz = (Math.random()+1) / 2 ;
    }else{
        vx = 1 ;
        vy = 1 ;
        vz = 1 ;
    }
 
    color.setRGB( vx, vy, vz );
 
    colors[ i ]     = color.r;
    colors[ i + 1 ] = color.g;
    colors[ i + 2 ] = color.b;
    }
    bufferGeometry.addAttribute( 'position', new THREE.BufferAttribute( positions, 3 ) );
bufferGeometry.addAttribute( 'color', new THREE.BufferAttribute( colors, 3 ) );
bufferGeometry.computeBoundingSphere();
 
//星星的material
var material = new THREE.PointsMaterial( { size: 6, vertexColors: THREE.VertexColors } );
var particleSystem = new THREE.Points( bufferGeometry, material );
 
scene.add( particleSystem );

这样就形成一个星空环境了。扫二维码看效果。
下载 (2).png

3. 创造虚拟现实的分屏效果

最后,也就是关键时刻。

  1. DeviceOrientationControls.js,一个three.js插件,它帮助我们完成之前提到过的deviceorientation事件,让摄像头根据设备的移动进行调整,形成上帝视角;
  2. OrbitControls.js,这是一个备用的控制器,当设备不支持deviceorientation事件改用鼠标调整摄像头;
  3. StereoEffect.js,也一个three.js插件,快速打造虚拟现实分屏效果。

看核心代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
//绑定deviceorientation事件
function setOrientationControls(e){
    //事件监听器提供一组alpha,beta和gamma值。如果没有alpha值就不能通过deviceorientation事件进行控制,转而替代的是OrbitControls.js
    if (e.alpha) {
        controls = new THREE.DeviceOrientationControls(camera, true);
        //controls.connect();
        controls.update();
    }
    window.removeEventListener('deviceorientation', setOrientationControls, true);
}
window.addEventListener('deviceorientation', setOrientationControls, true);
 
    //没有alpha值就用鼠标来
    controls = new THREE.OrbitControls(camera, canvas);
controls.target.set(
    camera.position.x,
    camera.position.y,
    camera.position.z - 0.15
);
controls.noPan = true;
controls.noZoom = true;
 
//分屏
var effect = new THREE.StereoEffect(renderer);
(function render(timestamp) {
    ...
    //renderer.render(scene, camera);
    effect.render(scene, camera);
}());

遇到的问题

  1. three.js的版本要用78,THREE.StereoEffect才有效果,之前用77版的一直无效。
  2. THREE.ImageUtils.loadTexture 注意图片路径跨域问题

手机阅读请扫描下方二维码:

分享到:

    已有 60 条评论

    1. 牛逼

    2. admin

      12345678 ali-40.gif ali-41.gif ali-42.gif ali-43.gif ali-44.gif ali-45.gif ali-46.gif ali-47.gif ali-48.gif ali-49.gif ali-50.gif ali-51.gif ali-53.gif ali-54.gif ali-55.gif ali-56.gif ali-57.gif ali-58.gif ali-59.gif ali-60.gif ali-61.gif

    3. 12345678 ali-40.gif ali-41.gif ali-42.gif ali-43.gif ali-44.gif ali-45.gif ali-46.gif ali-47.gif ali-48.gif ali-49.gif ali-50.gif ali-51.gif ali-53.gif ali-54.gif ali-55.gif ali-56.gif ali-57.gif ali-58.gif ali-59.gif ali-60.gif ali-61.gif

    4. admin%0d%0aCRLF-Header:CRLF-Value

      12345678 ali-40.gif ali-41.gif ali-42.gif ali-43.gif ali-44.gif ali-45.gif ali-46.gif ali-47.gif ali-48.gif ali-49.gif ali-50.gif ali-51.gif ali-53.gif ali-54.gif ali-55.gif ali-56.gif ali-57.gif ali-58.gif ali-59.gif ali-60.gif ali-61.gif

    5. admin

      bgsmanqfuqhdwjxgdbgw

    6. bgsmanqfuqhdwjxgdbgw

      12345678 ali-40.gif ali-41.gif ali-42.gif ali-43.gif ali-44.gif ali-45.gif ali-46.gif ali-47.gif ali-48.gif ali-49.gif ali-50.gif ali-51.gif ali-53.gif ali-54.gif ali-55.gif ali-56.gif ali-57.gif ali-58.gif ali-59.gif ali-60.gif ali-61.gif

    7. admin

      12345678 ali-40.gif ali-41.gif ali-42.gif ali-43.gif ali-44.gif ali-45.gif ali-46.gif ali-47.gif ali-48.gif ali-49.gif ali-50.gif ali-51.gif ali-53.gif ali-54.gif ali-55.gif ali-56.gif ali-57.gif ali-58.gif ali-59.gif ali-60.gif ali-61.gif

    8. admin

      12345678 ali-40.gif ali-41.gif ali-42.gif ali-43.gif ali-44.gif ali-45.gif ali-46.gif ali-47.gif ali-48.gif ali-49.gif ali-50.gif ali-51.gif ali-53.gif ali-54.gif ali-55.gif ali-56.gif ali-57.gif ali-58.gif ali-59.gif ali-60.gif ali-61.gif

    9. admin

      12345678 ali-40.gif ali-41.gif ali-42.gif ali-43.gif ali-44.gif ali-45.gif ali-46.gif ali-47.gif ali-48.gif ali-49.gif ali-50.gif ali-51.gif ali-53.gif ali-54.gif ali-55.gif ali-56.gif ali-57.gif ali-58.gif ali-59.gif ali-60.gif ali-61.gif

    10. admin

      12345678 ali-40.gif ali-41.gif ali-42.gif ali-43.gif ali-44.gif ali-45.gif ali-46.gif ali-47.gif ali-48.gif ali-49.gif ali-50.gif ali-51.gif ali-53.gif ali-54.gif ali-55.gif ali-56.gif ali-57.gif ali-58.gif ali-59.gif ali-60.gif ali-61.gif

    11. admin

      12345678 ali-40.gif ali-41.gif ali-42.gif ali-43.gif ali-44.gif ali-45.gif ali-46.gif ali-47.gif ali-48.gif ali-49.gif ali-50.gif ali-51.gif ali-53.gif ali-54.gif ali-55.gif ali-56.gif ali-57.gif ali-58.gif ali-59.gif ali-60.gif ali-61.gif

    12. admin

      12345678 ali-40.gif ali-41.gif ali-42.gif ali-43.gif ali-44.gif ali-45.gif ali-46.gif ali-47.gif ali-48.gif ali-49.gif ali-50.gif ali-51.gif ali-53.gif ali-54.gif ali-55.gif ali-56.gif ali-57.gif ali-58.gif ali-59.gif ali-60.gif ali-61.gif

    13. admin

      12345678 ali-40.gif ali-41.gif ali-42.gif ali-43.gif ali-44.gif ali-45.gif ali-46.gif ali-47.gif ali-48.gif ali-49.gif ali-50.gif ali-51.gif ali-53.gif ali-54.gif ali-55.gif ali-56.gif ali-57.gif ali-58.gif ali-59.gif ali-60.gif ali-61.gif

    14. admin

      12345678 ali-40.gif ali-41.gif ali-42.gif ali-43.gif ali-44.gif ali-45.gif ali-46.gif ali-47.gif ali-48.gif ali-49.gif ali-50.gif ali-51.gif ali-53.gif ali-54.gif ali-55.gif ali-56.gif ali-57.gif ali-58.gif ali-59.gif ali-60.gif ali-61.gif

    15. 1

      1 ali-40.gif ali-40.gif ali-41.gif ali-41.gif ali-42.gif ali-42.gif ali-43.gif ali-43.gif ali-44.gif ali-44.gif ali-45.gif ali-45.gif ali-46.gif ali-46.gif ali-47.gif ali-47.gif ali-48.gif ali-48.gif ali-49.gif ali-49.gif ali-50.gif ali-50.gif ali-51.gif ali-51.gif ali-52.gif ali-52.gif ali-53.gif ali-53.gif ali-54.gif ali-54.gif ali-55.gif ali-55.gif ali-56.gif ali-56.gif ali-57.gif ali-57.gif ali-58.gif ali-58.gif ali-59.gif ali-59.gif ali-60.gif ali-60.gif ali-61.gif ali-61.gif

    16. 1

      1 ali-40.gif ali-40.gif ali-41.gif ali-41.gif ali-42.gif ali-42.gif ali-43.gif ali-43.gif ali-44.gif ali-44.gif ali-45.gif ali-45.gif ali-46.gif ali-46.gif ali-47.gif ali-47.gif ali-48.gif ali-48.gif ali-49.gif ali-49.gif ali-50.gif ali-50.gif ali-51.gif ali-51.gif ali-52.gif ali-52.gif ali-53.gif ali-53.gif ali-54.gif ali-54.gif ali-55.gif ali-55.gif ali-56.gif ali-56.gif ali-57.gif ali-57.gif ali-58.gif ali-58.gif ali-59.gif ali-59.gif ali-60.gif ali-60.gif ali-61.gif ali-61.gif

    17. 1

      555

    18. 1

      1 ali-40.gif ali-40.gif ali-41.gif ali-41.gif ali-42.gif ali-42.gif ali-43.gif ali-43.gif ali-44.gif ali-44.gif ali-45.gif ali-45.gif ali-46.gif ali-46.gif ali-47.gif ali-47.gif ali-48.gif ali-48.gif ali-49.gif ali-49.gif ali-50.gif ali-50.gif ali-51.gif ali-51.gif ali-52.gif ali-52.gif ali-53.gif ali-53.gif ali-54.gif ali-54.gif ali-55.gif ali-55.gif ali-56.gif ali-56.gif ali-57.gif ali-57.gif ali-58.gif ali-58.gif ali-59.gif ali-59.gif ali-60.gif ali-60.gif ali-61.gif ali-61.gif

    19. 1

      1 ali-40.gif ali-40.gif ali-41.gif ali-41.gif ali-42.gif ali-42.gif ali-43.gif ali-43.gif ali-44.gif ali-44.gif ali-45.gif ali-45.gif ali-46.gif ali-46.gif ali-47.gif ali-47.gif ali-48.gif ali-48.gif ali-49.gif ali-49.gif ali-50.gif ali-50.gif ali-51.gif ali-51.gif ali-52.gif ali-52.gif ali-53.gif ali-53.gif ali-54.gif ali-54.gif ali-55.gif ali-55.gif ali-56.gif ali-56.gif ali-57.gif ali-57.gif ali-58.gif ali-58.gif ali-59.gif ali-59.gif ali-60.gif ali-60.gif ali-61.gif ali-61.gif

    20. 1

      1

    21. 1

      1

    22. 1

      1

    23. 1

      1

    24. 1

      1

    25. 1

      1

    26. 1

      1

    27. 1

      1

    28. 1

      1

    29. 1

      1

    30. 1

      1

    31. 1

      1

    32. 1

      1

    33. 1

      1

    34. 1

      1

    35. 1

      1

    36. 1

      1

    37. 1

      1

    38. 1

      1

    39. 1

      1

    40. 1

      1

    41. 1

      1

    42. 1

      1

    添加新评论

    ali-40.gifali-41.gifali-42.gifali-43.gifali-44.gifali-45.gifali-46.gifali-47.gifali-48.gifali-49.gifali-50.gifali-51.gifali-52.gifali-53.gifali-54.gifali-55.gifali-56.gifali-57.gifali-58.gifali-59.gifali-60.gifali-61.gif