21. WebAR那些事: ARDemo之《天马行空》

紧接上文

使用WebAR技术,开发者只需40行代码,即可搭建一个ARDemo。同时我们也抛出了一个问题,如果把地球模型,换成一个可以动的小猫小狗,是不是就更加接近虚拟现实了?

本次Demo所需二维码

本次demo已经集成到APK中,用户可以点击《天马星空》来体验。
21. WebAR那些事: ARDemo之《天马行空》

天马星空

环境准备

  1. Demo使用r82版本,向下兼容
  2. Three.js 到http://www.threejs.org下载最新源码,这里使用three.min.js作为渲染引擎。
  3. WebVR.js WebVR的工具库,用于切换VR状态(three.js的源码包中,自己拷贝)
  4. VREffect.js WebVR的展示库,用于分屏展示(three.js的源码包中,自己拷贝)
  5. VRControls.js WebVR的控制库,用于监控陀螺仪、Camera、重力等(three.js的源码包中,自己拷贝)

3D模型

之前我们总是使用地球的3D模型,估计各位看官也看腻了,这次终于更新了!

  1. 支持动画的3D模型
    通过阅读THREE.JS的示例,找到了喜欢的模型,一批奔跑的马儿。

在webgl分类下的shadowmap入口,可以看到官方的demo。

  1. 3D模型的格式
    本次演示的3D模型,是JSON格式,可以有多种工具生成,比如3DMax、玛雅等。

这种格式虽然方便阅读,缺点也比较明显,将整个文件解析成json后,再转换成内存数据,最后上传到GPU,由于JS语言在运算处理方面的不足,加载过程会稍慢一些。

  1. WebVRSDK支持的3D格式
    打开THREE.JS的官方example,可以看到loder分类的3D模型格式,初步可以理解为,只要three.js支持的格式,WebVRSDK也是可以支持的。如果有不支持,请反馈给我,我会及时更新WebVRSDK

兼容性准备

获取摄像头API,目前只支持Navigator.getUserMedia

index.js核心代码

核心代码量约50行,核心代码和《上一篇》基本一致,只是将3D地球的模型,替换成了一批马。

代码参考Three.js,如下

var w = window.innerWidth;
var h = window.innerHeight;
var renderer = new THREE.WebGLRenderer();        // 创建渲染器
renderer.setSize(w, h);                            // 设置渲染器为全屏
document.body.appendChild(renderer.domElement);    // 将渲染器添加到body上

var horse, delta;
var clock    = new THREE.Clock();                // 创建时钟
var scene    = new THREE.Scene();                // 创建场景
var mixer    = new THREE.AnimationMixer(scene);    // 创建混合器
var camera    = new THREE.PerspectiveCamera(45, w / h, 100, 3000);

var control    = new THREE.VRControls(camera);        // 控制器,用来控制摄像机
var effect    = new THREE.VREffect(renderer);        // 控制器,用来控制VR渲染
var loader    = new THREE.JSONLoader();            // 加载器,用于加载3D模型
loader.load("horse.json", function(geometry) {
    var material = new THREE.MeshLambertMaterial({ color: 0xFFAA55, morphTargets: true, vertexColors: THREE.FaceColors });
    horse = new THREE.Mesh(geometry, material);
    horse.speed         = 200;
    horse.position.x = -500;
    
    scene.add(horse);
    scene.add(new THREE.AmbientLight(0x444444));// 创建环境光
    scene.add(new THREE.DirectionalLight(0xFFFFFF, 1, 0));
    mixer.clipAction(geometry.animations[0], horse).setDuration(1).startAt(-Math.random()).play();
});
window.navigator.getUserMedia({ audio : true, video: { width: w, height: h }}, function(stream) {
    var video = document.createElement('video');
    video.src = stream;
    video.play();

    var image = new THREE.VideoTexture(video);
    image.generateMipmaps = false;
    image.format     = THREE.RGBAFormat;
    image.maxFilter  = THREE.NearestFilter;
    image.minFilter  = THREE.NearestFilter;
    scene.background = image;                    // 背景视频纹理
}, null);

animate();
function animate() {
    effect.requestAnimationFrame(animate);
    if (horse) {
        delta = clock.getDelta();
        mixer.update(delta);
        horse.position.z += horse.speed * delta;
        if (horse.position.z > 1000) {
            horse.position.z = -1000 - Math.random() * 500;
        }
    }
    control.update();
    effect.render(scene, camera);
}

效果展示

很想把屏幕录制下来,再制成GIF格式的图片,方便演示,大家有没有推荐的工具软件,最好能直接截屏的那种。
演示的效果,大概是这样子的,一匹马从远处跑来,然后再跑到远处,直至消失。用两张图片大概来演示吧。。

21. WebAR那些事: ARDemo之《天马行空》

21. WebAR那些事: ARDemo之《天马行空》

畅想

WebAR入门简单

写这篇文章的时候,我也想不到,只需要50行代码,就可以做一个带有动画的ARDemo,不得不说Three.js太强大了。
那问题来了,既然代码都是用标准的JS写的,而且框架用的是开源的Three.js,那WebVRSDK做了什么?
WebVRSDK是使用C/C++编写的<跨平台><极简><高性能>的<浏览器>内核,大小在400K以下,以WebGL为核心,支持WebGL、Canvas、Video、Audio、XMLHttpRequest、VRDisplay、Camera、ImageDecode等等,但不支持Dom,并且为Three.js/Pixi.js/Tiny.js等做了深度兼容。
所以,前端开发者,只需要在PC浏览器开发、调试通过,就可以快速的移植到WebVRSDK平台。

千锤百炼才是精品

我对JS的理解还属于入门级别,目前写的Demo,基本都是临时学的,不要太当真。
想做好WebAR/VR,还需要前端大牛的支持。
如果有好的产品,欢迎移植&对接WebVRSDK。

下一回

添加个按钮,让AR可以和用户交互,但
加个什么按钮呢?
点击按钮之后,显示什么效果呢?
敬请期待

上一篇:22. WebAR那些事: 20行代码做全景


下一篇:让你的 Qt 桌面程序看上去更加 native(六):跨平台技术