20. WebAR那些事: 一个40行的ARDemo

简介: #紧接上文 WebVR+Three.js可以快速高效的搭建VR场景,降低了初学者的准入门槛,节省多平台重复开发,开始了H5在VR的新时代。 #本次Demo所需二维码 用户可以本地启动HTTP服务,将URL填写到播放路径 本次demo已经集成到APK中,用户可以点击《AR地球》来体验 ![1480510893.png](http://ata2-img.cn-hangzhou.img-p

紧接上文

WebVR+Three.js可以快速高效的搭建VR场景,降低了初学者的准入门槛,节省多平台重复开发,开始了H5在VR的新时代。

本次Demo所需二维码

用户可以本地启动HTTP服务,将URL填写到播放路径
本次demo已经集成到APK中,用户可以点击《AR地球》来体验
1480510893.png

AR地球

环境准备

  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模型,为了方便起见,我们使用老的模型

  1. 地球纹理,在网上可以找到最新的地图纹理,最好使用4k,比较清晰
    earth_map_jpeg

兼容性准备

常见的浏览器对摄像头的支持,良莠不齐,这里只是简单的支持了一种API标准

捕获音视频接口: Navigator.getUserMedia

点击进入: Mozilla官方使用文档
使用方法:

var params = { video: true, video: { width: 1280, height: 720 } };
window.navigator.getUserMedia(params, function(stream) {
    var video = document.querySelector('video');
    video.src = window.URL.createObjectURL(stream);
    video.onloadedmetadata = function(e) {
        video.play();
    };
});

兼容性分析

Navigator.getUserMedia接口目前Safari是不支持的,常见的浏览器使用摄像头,往往通过Flash插件来完成。所以这些代码不一定能够成功运行在用户的浏览器上,但没有关系,我们的的WebVRSDK已经提供了支持,开发者可以放心的使用。
Navigator.getUserMedia已经废弃了,使用MediaDevices.getUserMedia来取代。因为我对Promise原理不是很清楚,所以暂时只支持Navigator.getUserMedia。
开发者需要提前申请App的Camera权限,Android6.0以后支持动态权限管理,开发者需要确保App拥有Camera的使用权限,最直接的的办法是在设置中手动的打开权限,否则背景会出现黑屏。

准备空白的html

我们会将所有JS代码写在单独的index.js中,因此index.html只是提供JS运行的环境,这一步为代码迁移到WebVRSDK做准备。代码如下:

<!doctype html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>WebGL Earth</title>
    <style>
        body { margin: 0; overflow: hidden; background-color: #000; }
    </style>
</head>
<body>
    <script src="three.js"></script>
    <script src="WebVR.js"></script>
    <script src="VREffect.js"></script>
    <script src="VRControls.js"></script>
    <script src="index.js"></script> 
</body>
</html>

index.js核心代码

  1. 代码行数控制在40行以内
  2. 渲染器,使用WebGL渲染three.js中的3D对象
  3. 加载器,使用XMLHttpRequest或者Image,异步加载图片纹理
  4. 摄像机,模拟观察者的位置和方向,从不同角度来观看3D世界
  5. 控制器,接受用户点击、触摸、鼠标等事件,控制摄像机的参数,实现人机交互
  6. 材料,任何3D对象,是由骨骼和图像组成,材料就像油漆,粉刷过的对象更加真实
  7. 几何,3D对象的结构描述,这里只用球状几何
  8. 场景,用来管理所有需要展示的3D对象,以及他们之间的层级和关系
  9. video标签,用于承载摄像头内容的呈现

代码如下

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

var camera    = new THREE.PerspectiveCamera(45, w / h, 0.01, 100);
var effect    = new THREE.VREffect(renderer);        // 控制器,用来控制VR渲染
var loader    = new THREE.TextureLoader();        // 加载器,用于异步加载图片
var control    = new THREE.VRControls(camera);        // 控制器,用来控制摄像机

var mater = { map : new THREE.TextureLoader().load('earth_map.jpg') };
var earth = new THREE.Mesh(new THREE.SphereGeometry(20, 32, 32), new THREE.MeshBasicMaterial(mater));
earth.position.x = -100;

var scene  = new THREE.Scene();                    // 创建场景
scene.add(earth);                                // 添加地球
scene.add(new THREE.AmbientLight(0xFFFFFF));    // 创建环境光

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);
    control.update();
    earth.rotation.y += 0.002;
    effect.render(scene, camera);
}

用浏览器打开index.html

在Safari上是无法打开的,因为navigator没有成员函数:getUserMedia
开发者可以添加判断,因为WebVRSDK我添加了支持,所以就不判断了,代码如下:

navigator.getUserMedia = navigator.getUserMedia        ||
                         navigator.mozGetUserMedia    ||
                         navigator.webkitGetUserMedia;

if (navigator.getUserMedia) {
    ....
}

效果展示

悬浮的3D地球
a1f0a50aacd8308bcccbf7f5f99aa22e.jpg

畅想

AR距离我们很近

AR翻译过来是增强现实,简单一点说,就是在摄像头捕获的视频或者图片中,加入3D效果,并融入背景。就像二次元或者三次元一样,给用户带来更多的欢乐。

如果我们把3D地球换成一只可爱的猫咪,是不是就是淘宝双十一的抓猫猫游戏了?

下一回

我们把地球换成一个复杂的3D模型,并想办法让TA动起来,就像淘宝双十一的AR抓猫猫一样,会动会跳,还会发红包。

目录
相关文章
|
Windows
Winform控件优化之背景透明那些事1:Button控件等背景透明
WinForm不支持真正的透明,其控件透明的实现都是背景颜色设置和对应位置的父控件背景相同。 Winform中控件的背景透明只有三种:Button控件的透明、其他控件的透明...
2453 0
Winform控件优化之背景透明那些事1:Button控件等背景透明
|
消息中间件 Java 物联网
一文搞懂MQTT,如何在SpringBoot中使用MQTT实现消息的订阅和发布
之前介绍了RabbitMQ以及如何在SpringBoot项目中整合使用RabbitMQ,看过的朋友都说写的比较详细,希望再总结一下目前比较流行的MQTT。所以接下来,就来介绍什么MQTT?它在IoT中有着怎样的作用?如何在项目中使用MQTT?
8526 5
一文搞懂MQTT,如何在SpringBoot中使用MQTT实现消息的订阅和发布
|
前端开发
Threejs - 加载视频纹理渲染 实现一个3D视频播放器
Threejs - 加载视频纹理渲染 实现一个3D视频播放器
1806 0
Threejs - 加载视频纹理渲染 实现一个3D视频播放器
|
安全 数据库连接 数据库
Navicat16最新版破解激活教程,亲测可用
本篇文章教大家如何破解 Navicat,Navicat是一套快速、可靠并价格相宜的数据库管理工具,专为简化数据库的管理及降低系统管理成本而设。它的设计符合数据库管理员、开发人员及中小企业的需要。Navicat 是以直觉化的图形用户界面而建的,让你可以以安全并且简单的方式创建、组织、访问并共用信息。
7410 0
|
消息中间件 Cloud Native 前端开发
Spring Cloud Alibaba 2021.0.1.0 版本发布啦
本次隆重发布的 Spring Cloud Alibaba 2021.0.1.0 版本在 Spring Cloud 2021.0.1、Spring Boot 2.6.3 的基础上对其中包括注册配置中心、分布式消息等在内的众多组件进行重大升级。
4943 2
Spring Cloud Alibaba 2021.0.1.0 版本发布啦
|
7月前
|
编解码 网络协议 应用服务中间件
公网可用的RTMP、RTSP测试地址
好多博客提到的公网可测试的RTSP和RTMP URL大多都不用了,以下是大牛直播SDK(Github)于2021年3月亲测可用的几个URL,有其他可用的URL,也欢迎大家在评论区回复。
6296 0
|
Java Android开发
Eclipse打不开,出现an error has occured see the log file(日志中出现!MESSAGE FrameworkEvent ERROR !STACK 0)问题
Eclipse打不开,出现an error has occured see the log file(日志中出现!MESSAGE FrameworkEvent ERROR !STACK 0)问题
574 0
Eclipse打不开,出现an error has occured see the log file(日志中出现!MESSAGE FrameworkEvent ERROR !STACK 0)问题
|
Ubuntu 前端开发 测试技术
Nginx-性能优化-ab压力测试工具
Apache Benchmark(简称ab) 是Apache安装包中自带的压力测试工具 ,简单易用。
743 0
Nginx-性能优化-ab压力测试工具
|
Linux Go Windows
在Windows、Linux上安装GO并且运行第一个程序(1)
在Windows、Linux上安装GO并且运行第一个程序
121 0
在Windows、Linux上安装GO并且运行第一个程序(1)
|
存储 Ubuntu Linux
阿里云服务器Linux系统挂载数据盘教程
Linux系统挂载U盘或硬盘教程(查看、分区、格式化、挂载)
1730 0