Augmented Reality
噔噔!一个类似阴阳师现世抽卡的小demo,由于getUserMedia的兼容性问题,目前只有安卓手机可以看到...(建议拿一些高端点的安卓机)
玩法:扫左图的二维码后,点击允许访问摄像头后,再扫右边的二维码(相当于阴阳师里的召唤阵)
或者你也可以拿另外一台手机扫下面的码来显示召唤阵
下面探索一下其实现的原理,其中主要的交互包括:
开启摄像头 > 扫码 > 显示模型
转换为相对应的技术,奏是...
· getUserMedia,开启摄像头获取设备的媒体信息
· OpenCv,js-aruco, 图像处理,识别二维码
· 画出3d模型,threejs,threex_webar, MMDLoader-app
· 进一步交互(TO DO)
1. 开启摄像头
getUserMedia提示用户允许使用一个视频和/或一个音频输入设备,如果用户给予许可,successCallback回调就会被调用。第一个参数指定了请求使用媒体的类型
1 2 3 4 | navigator.getUserMedia ( { video: true , // 这里只请求相机 audio: false }, successCallback, errorCallback ); |
1) 后摄像头
getUserMedia默认是开启前摄像头的,被突然出现的丑萌的自己吓到...这不是我们想要的效果。。解决方案是利用MediaStreamTrack遍历设备的媒体源,返回后摄像头的sourceId
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 | // 遍历设备的媒体源 MediaStreamTrack.getSources( function (sourceInfos) { //getUserMedia的constraints参数 var constraints = { video: true , audio: false } for ( var i = 0; i != sourceInfos.length; ++i) { var sourceInfo = sourceInfos[i]; // 后摄像头 if (sourceInfo.kind == "video" && sourceInfo.facing == "environment" ) { constraints.video = { optional: [{sourceId: sourceInfo.id}] } } } navigator.getUserMedia( constraints, function (stream){ video.src = URL.createObjectURL(stream); //获取到的视频流传给页面上的video来显示 }, function (error) { alert(error.message); }); }); |
2) 全屏问题
1 | 拍摄的内容并没有全屏显示,解决方案就是:在video外层增加一个div并且设置为浏览器宽高,再增加 overflow:hidden,注意video不用设宽高,这样就可以模拟全屏的效果了 |
2. js-aruco
js-aruco是一个Aruco库的js,而Aruco是一个基于OpenCv的图像处理库,大概的作用就是可以识别图片的轮廓,这样就可以达到扫码的作用来做进一步的交互了。
js-aruco可识别的图片要满足以下要求:一张7x7的网格图(类似一张二维码),最外一层是黑色的,然后中间5x5的网格每一行都要遵循下列规则之一
white - black - black - black - black
white - black - white - white - white
black - white - black - black - white
black - white - white - white - black
(可以看到刚刚扫过的id:256二维码就满足以上规则)
不同的组合拼成不同的二维码,每一个二维码都有对应的id。(戳demo)[https://test.nie.163.com/test_html/test/dropping/js_aruco.html]
3. threex_webar
threex_webar
直接就把前面的步骤都封装好,让你把注意力放在画3d模型上。
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 jsArucoMarker = new THREEx.JsArucoMarker(); //视频图像采集 var videoGrabbing = new THREEx.WebcamGrabbing(); //建立一个Object3D对象 var markerObject3D = new THREE.Object3D() scene.add(markerObject3D) //把3d模型画在Object3D对象上, 待会下一步会详细说明 drawMMDmodel(); //一开始设为不可见 markerObject3D.visible= false ; onRenderFcts.push( function (){ var domElement = videoGrabbing.domElement var markers = jsArucoMarker.detectMarkers(domElement) markerObject3D.visible = false //等识别到二维码后,显示Object3D对象 markers.forEach( function (marker){ jsArucoMarker.markerToObject3D(marker, markerObject3D) markerObject3D.visible = true ; }) }) |
注意事项
上面提到的摄像内容的全屏问题
1 2 3 | //要去修改下threex_webar的threex.webcamgrabbing.js,取消默认设置的宽高 //domElement.style.width = '100%' //domElement.style.height = '100%' |
4. 3d model
MMDLoader-app绘制mmd模型
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 | function drawMMDmodel() { //模型加载成功回调 var onProgress = function (xhr) { if (xhr.lengthComputable) { var percentComplete = xhr.loaded / xhr.total * 100; console.log(Math.round(percentComplete, 2) + '% downloaded' ); } }; //模型加载失败回调 var onError = function (xhr) {}; //Polygon Model Document,一种三维模型格式 //Vocaloid Motion Data,模型动作 var vmdFiles = [ 'https://cdn.rawgit.com/mrdoob/three.js/dev/examples/models/mmd/vmds/wavefile_v2.vmd' ]; helper = new THREE.MMDHelper(); var loader = new THREE.MMDLoader(); loader.load(modelFile, vmdFiles, function (object) { mesh = object; mesh.scale.set(1, 1, 1).multiplyScalar(1 / 35); mesh.rotation.x = Math.PI / 2; mesh.material = makePhongMaterials(mesh.material.materials); var i = 0, materials = mesh.material.materials, len = materials.length; for (; i < len; i++) { materials[i].emissive.multiplyScalar(1); } helper.add(mesh); helper.setAnimation(mesh); helper.setPhysics(mesh); helper.unifyAnimationDuration(); markerObject3D.add(mesh); ready = true ; }, onProgress, onError); } |
参考资料
http://tgideas.qq.com/webplat/info/news_version3/804/7104/7106/m5723/201612/537832.shtml
https://developer.mozilla.org/zh-CN/docs/Web/API/Navigator/getUserMedia
http://opencv.org/
手机阅读请扫描下方二维码:
66666
12345678
12345678
12345678
12345678

1
12345678
'//and(select'1'from//pg_sleep(0))>'0
12345678

12345678
12345678
12345678
555
1
555
555
555
1
12345678
12345678
12345678
1
1
1
1
1
1
1
1
1
1
1
1
你是不是傻
12345678

12345678

expr 998959313 + 951554523
12345678
|expr 950201404 + 825031481
12345678
$(expr 821787452 + 811484489)
12345678
&set /A 952028606+893291760
12345678

${@var_dump(md5(637484447))};
'-var_dump(md5(421910437))-'
12345678

12345678

/1/{{881478682+886874052}}
lpdzutietyzjtbwevffd
${991909220+852870805}
12345678

12345678

12345678

12345678

12345678

12345678

12345678

12345678

12345678

12345678

12345678

12345678

1

1

555
1

1

1
1
1
555
1
1
1
1
1
1
555
1
1
555
1
555
1
1
1
1
1
1
1
1
1
1
1
1
1
1
555
1
1