增强现实技术(Augmented Reality,简称 AR),是一种实时地计算摄影机影像的位置及角度并加上相应图像、视频、3D模型的技术,这种技术的目标是在屏幕上把虚拟世界套在现实世界并进行互动。这种技术1990年提出。随着随身电子产品CPU运算能力的提升,预期增强现实的用途将会越来越广。

本文介绍使用JavaScript开源框架AR.js实现的增强现实的Hello World例子。

先看效果:

首先在手机浏览器里打开我部署在github page上的这个demo应用:

i042416.github.io/FioriODataT…

我用的是Android手机安装的Chrome浏览器。

打开网页,会提示你是否允许这个网页应用访问您的手机摄像头。点击允许:

用手机上的摄像头扫描这张图片:

神奇的事情就发生了。您会看到,通过手机摄像头望过去,手机屏幕里会出现一个新的不断滚动的3D物体,如下图所示。

下面具体介绍这个最简单的例子是怎么开发出来的。

所有的源代码在我的github上:

github.com/i042416/Fio…

新建一个html文件,把下列150行代码粘贴进去,然后在服务器上运行,使用之前描述的步骤即可进行AR测试:

<!DOCTYPE html>
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0"><script src='ar/lib/three.min.js'></script>
<script src="ar/lib/stats.min.js"></script>
<script src="ar/lib/ar.js"></script><script>
debugger;THREEx.ArToolkitContext.baseURL = '';
</script>
<body style='margin : 0px; overflow: hidden; font-family: Monospace;'>
<div style='position: absolute; top: 10px; width:100%; text-align: center; z-index: 1;'><script>var renderer = new THREE.WebGLRenderer({// antialias    : true,alpha: true});renderer.setClearColor(new THREE.Color('lightgrey'), 0)// renderer.setPixelRatio( 1/2 );renderer.setSize( window.innerWidth, window.innerHeight );renderer.domElement.style.position = 'absolute'renderer.domElement.style.top = '0px'renderer.domElement.style.left = '0px'document.body.appendChild( renderer.domElement );// array of functions for the rendering loopvar onRenderFcts= [];// init scene and cameravar scene    = new THREE.Scene();var camera = new THREE.Camera();scene.add(camera);var arToolkitSource = new THREEx.ArToolkitSource({// to read from the webcam sourceType : 'webcam',// to read from an image// sourceType : 'image',// sourceUrl : THREEx.ArToolkitContext.baseURL + '../data/images/img.jpg',       // to read from a video// sourceType : 'video',// sourceUrl : THREEx.ArToolkitContext.baseURL + '../data/videos/headtracking.mp4',     })arToolkitSource.init(function onReady(){onResize()})window.addEventListener('resize', function(){onResize()})function onResize(){arToolkitSource.onResize() arToolkitSource.copySizeTo(renderer.domElement) if( arToolkitContext.arController !== null ){arToolkitSource.copySizeTo(arToolkitContext.arController.canvas) }   }var arToolkitContext = new THREEx.ArToolkitContext({// cameraParametersUrl: THREEx.ArToolkitContext.baseURL + '../data/data/camera_para.dat',cameraParametersUrl: 'ar/data/data/camera_para.dat',detectionMode: 'mono',maxDetectionRate: 30,canvasWidth: 80*3,canvasHeight: 60*3,})arToolkitContext.init(function onCompleted(){camera.projectionMatrix.copy( arToolkitContext.getProjectionMatrix() );})onRenderFcts.push(function(){if( arToolkitSource.ready === false ) return;arToolkitContext.update( arToolkitSource.domElement )})var markerRoot = new THREE.Groupscene.add(markerRoot)var artoolkitMarker = new THREEx.ArMarkerControls(arToolkitContext, markerRoot, {type : 'pattern',patternUrl : THREEx.ArToolkitContext.baseURL + 'ar/data/data/patt.hiro'})// build a smoothedControlsvar smoothedRoot = new THREE.Group()scene.add(smoothedRoot)var smoothedControls = new THREEx.ArSmoothedControls(smoothedRoot, {lerpPosition: 0.4,lerpQuaternion: 0.3,lerpScale: 1,})onRenderFcts.push(function(delta){smoothedControls.update(markerRoot)})var arWorldRoot = smoothedRoot// add a torus knot var geometry    = new THREE.CubeGeometry(1,1,1);var material   = new THREE.MeshNormalMaterial({transparent : true,opacity: 0.5,side: THREE.DoubleSide}); var mesh = new THREE.Mesh( geometry, material );mesh.position.y = geometry.parameters.height/2arWorldRoot.add( mesh );var geometry = new THREE.TorusKnotGeometry(0.3,0.1,64,16);var material  = new THREE.MeshNormalMaterial(); var mesh = new THREE.Mesh( geometry, material );mesh.position.y = 0.5arWorldRoot.add( mesh );onRenderFcts.push(function(){mesh.rotation.x += 0.1})var stats = new Stats();document.body.appendChild( stats.dom );// render the sceneonRenderFcts.push(function(){renderer.render( scene, camera );stats.update();})// run the rendering loopvar lastTimeMsec= nullrequestAnimationFrame(function animate(nowMsec){// keep loopingrequestAnimationFrame( animate );// measure timelastTimeMsec  = lastTimeMsec || nowMsec-1000/60var deltaMsec = Math.min(200, nowMsec - lastTimeMsec)lastTimeMsec    = nowMsec// call each update functiononRenderFcts.forEach(function(onRenderFct){onRenderFct(deltaMsec/1000, nowMsec/1000)})})
</script></body>
复制代码

当然,这个效果来自大神jeromeetienne开源的AR.js:

github.com/jeromeetien…

当然大神自己也很谦虚地提到,他这个开源的增强现实框架也是建立在巨人的肩膀上开发的:比如其中3D效果的绘制,使用到了另一个开源框架three.js:

要获取更多Jerry的原创文章,请关注公众号"汪子熙":

150行JavaScript代码实现增强现实相关推荐

  1. 只要200行JavaScript代码,就能把特斯拉汽车带到您身边

    Jerry的前一篇文章 如何使用JavaScript开发AR(增强现实)移动应用 (一) 介绍了用React-Native + ViroReact开发增强现实应用的一些预备知识. 本文咱们开始进入增强 ...

  2. 100行JavaScript代码实现JavaScript

    先看效果: 100行JavaScript代码实现经典游戏俄罗斯方块 新建一个html文件,复制如下代码,用浏览器打开即可: <!doctype html> <html> < ...

  3. 60行JavaScript代码写俄罗斯方块

    教你看懂网上流传的60行JavaScript代码俄罗斯方块游戏 早就听说网上有人仅仅用60行JavaScript代码写出了一个俄罗斯方块游戏,最近看了看,今天在这篇文章里面我把我做的分析整理一下(主要 ...

  4. [原创]22行JavaScript代码实现QQ群成员提取器,绿色、环保、无病毒!

    原来想给QQ群内的成员发邮件,找了一个现成的软件,没想到居然有QQ盗号病毒,很不爽.就决定自己动手,丰衣足食. 首先,我想到如果能够直接从QQ群成员列表中把所有成员拷贝出来,岂不是很方便.不过QQ明显 ...

  5. easyui treegrid 获取新添加行inserted_18行JavaScript代码构建一个倒数计时器

    有时候,你会需要构建一个JavaScript倒计时时钟.你可能会有一个活动.一个销售.一个促销或一个游戏.你可以用原生的JavaScript构建一个时钟,而不是去找一个插件.尽管有很多很棒的时钟插件, ...

  6. 详解用65行javascript代码做Flappy Bird

    点击查看特效 JavaScript做Flappy Bird游戏,代码仅仅65行 资源包括: javascript源码:phaser.min.js:main.js:index.html 素材:两张图片! ...

  7. 如何用 200 行 JavaScript 代码实现人脸检测?

    在超市.地铁.车站等很多场景中,人脸识别已经被广泛应用,但是这个功能究竟是怎么实现的? 在本文中,将以 pico.js 库为例,分享实现轻量级人脸识别功能的具体开发过程 . 作者 | tehnokv ...

  8. python写计算机模拟器_用 150 行 Python 代码写的量子计算模拟器

    这是个 GItHub 项目,可以简单了解一下. qusim.py 是一个多量子位的量子计算机模拟器(玩具?),用 150 行的 python 所编写. 这段代码可以让你轻松了解量子计算机如何遵循线性代 ...

  9. 【转】265行JavaScript代码的第一人称3D H5游戏Demo

    译文:http://blog.jobbole.com/70956/ 原文:http://www.playfuljs.com/a-first-person-engine-in-265-lines/ 这是 ...

最新文章

  1. ffmpeg文件拼接
  2. build的时候出错,fatal error LNK1103
  3. (原创)c#学习笔记08--面向对象编程简介01--面向对象编程的含义03--对象的生命周期--构造函数和析构函数...
  4. vscode输入vue自动_vscode配置总结可收藏/vscode用户设置大全/vue代码模板,vscodevue...
  5. 从直觉主义到量化分析 让大数据做主
  6. 存储引擎放弃使用索引的方式
  7. 使用SAP Cloud for Customer Product OData服务读取产品主数据和其图片信息
  8. MySQL笔记 - 用户管理
  9. Vue的基本环境搭建
  10. postgresql9.6 的安装
  11. 凸包板子试炼(玄学过题)
  12. 【愣锤笔记】能解决80%场景的Git必会知识点
  13. html 置换元素和非置换元素
  14. Mysql中使用逗号隔开多张表生成的表实例
  15. 2022 最新 IntelliJ IDEA 2022 详细配置步骤演示(图文版)
  16. [论文解读]Deep active learning for object detection
  17. 计算机维修行业中年,35岁改行的5个职业 中年转行也很轻松,你选对了吗
  18. 网络爬虫-腾讯支付encrypt_msg参数逆向
  19. git中submodule子模块的添加、使用和删除
  20. 《Android移动应用基础教程》之Android购物商城

热门文章

  1. SQL---空字符串不等于null
  2. 执行RMAN恢复的高级场景_通过网络还原和恢复文件
  3. php生成pdf文件,html转pdf文件的最佳方法(转载)
  4. 一招搞定小白最头疼的数据大屏配色问题!
  5. 牛客每日练习----珂学送分,捡石头,良神爱购物
  6. Angular2+ 表单主动触发验证
  7. 【SARIMAX】Champagne Sales
  8. UG OPEN C API 函数参考手册(nx6) CHM版
  9. mysql查询一周内数据并分组_mysql 统计本周7天的数据并分组
  10. chatgpt赋能python:Python中的空格:到底是重要的还是无关紧要的?