Web AR 入門: AR.js Tracking.js Three.js A-frame.js
WebAR 可拆分兩個部分相機與圖片識別
和3D模型
其實不名思義就是使用相機取得現實中的畫面作為背景,在藉由相當的 圖片辨識 的技術,在特定的座標位置,渲染出對應的 3D 模型,使使用者感受到與現實做連結,也就是 增强現實 (簡稱為 AR)
根據上面的敘述,我們可獨立分成兩個部分進行說明,這也是我個人在學習 Web AR 時,所得知的結論與紀錄
最廣受人知的 AR 範例:PokeMon GO
WebAR
- 取得攝像鏡頭畫面
- 圖片識別
- 3D 圖形繪製與操作
相機與圖片識別
取得攝像鏡頭畫面
我們使用 HTML5 提供的 API navigator.mediaDevices.getUserMedia
就可以很輕鬆的達到我們想要的效果了 (需使用有攝像鏡頭的裝置進行測試)
範例如下:
<video id="video" width="640" height="480" autoplay>
<script>
const video = document.getElementById('video');
if(navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
// Not adding `{ audio: true }` since we only want video now
navigator.mediaDevices.getUserMedia({ video: true }).then(function(stream) {
video.src = window.URL.createObjectURL(stream);
video.play();
});
}
</script>
圖片識別
其實這部分才是 AR 這項技術最大的學問
這部分涉略了很多 複雜 的演算法、數據分析
像是 Google 提供的 Tensorflow 的 Tensorflow Object Detection (自動辨識物件)
光看影片就覺得很牛對吧?而且還是牛的一塌糊塗~~
不過呢,這邊並不會去說明如何使用 Tensorflow Object Detection,這都可以獨立開個主題來說明了,所以這邊就先簡單帶過~
建議剛接觸這塊可以先從其他比較容易理解的套件和工具下手 :
Tracking.js
可以對影片圖片與鏡頭的畫面進行臉部辨識與色彩辨識 等等....
且官網上都有詳細的說明和 Demo,非常容易入手
AR.js
這是玩 Web AR 不能不知道的套件,由 Jeromeetienne 所開發的套件,宣稱速度快、高效能,且只要使用 10 行 HTML 的代碼,就可以產生出一個 AR 的應用了
非常的厲害,這是作者提出的 AR.js 的範例:
<!doctype HTML>
<html>
<script src="https://aframe.io/releases/0.6.1/aframe.min.js"></script>
<script src="https://cdn.rawgit.com/jeromeetienne/AR.js/1.5.0/aframe/build/aframe-ar.js"> </script>
<body style='margin : 0px; overflow: hidden;'>
<a-scene embedded arjs>
<a-marker preset="hiro">
<a-box position='0 0.5 0' material='color: black;'></a-box>
</a-marker>
<a-entity camera></a-entity>
</a-scene>
</body>
</html>
可以在作者的 CodePen 裡面,查看呈現出的結果,關於這 10 行的 HTML 代碼,作者有在 medium 做很詳細的說明
另外作者在 GitHub 中有提到 Three.js
與 Artoolkit
,Three.js
是處理 3D 繪圖的 JavaScript FrameWork, 這邊於 3D 圖形時,後面會做介紹,這邊先提 Artoolkit
Artoolkit
Artoolkit
是 AR.js
在處理圖片辨識的核心,是一個由 C/C++ 語言所撰寫的函示庫,主要是以 標記 (Marker)
作為在相機中,取得相對位置的依據
而 AR.js 則是藉由取得到的座標,去渲染由 Three.js
所產生出的 3D 模型
自訂 AR.js 的 Marker
當然這個 標記 (Marker)
是可以被自訂的
AR.js 的作者也很貼心的製作了簡單工具,我們可以簡單的上傳圖片就可以產生自訂的 標記 (Mark)
了
可以直接到作者的 Medium: How To Create your Own Marker ? 進行製作
不過作者有建議, Marker 的部分,最好都是要有黑邊的,具體的原因我不是很清楚,不過應該是可以提高辨識度的吧
如果想要直接使用 自然圖片 (無黑邊) 作為 AR.js 的 Marker 也是做的到的,最近剛好在知呼這個論壇內,有看到有人在介紹,可以直接參考 AR.js 初探 進行製作
3D 圖形繪製與操作
因為我覺得 WebGL 有難度點高,對於 初學者 而言 Three.js 比較友善些
有在處理 網站特效 的人都知道,我們會使用 x 或者 y 的座標,來進行一些動態的效果,我們稱呼為 二維 , 恭喜接下來將進入 三維 ,也就是 3D 的世界
這篇文章並不會教你如何計算 微積分、矩陣、三角函數、向量
這邊單純概述一下基本的 3D 圖形組成
- FPS (幀數)
- camera (相機 or 視角)
- Scene (舞臺)
我們直接使用 Three.js 繪製一個簡單的方體(這邊的範例,還不涉及動畫 所以還不會有 FPS 的部分)
初期準備:
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8>
<title>My first Three.js app</title>
<style>
body { margin: 0; }
canvas { width: 100%; height: 100% }
</style>
</head>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/95/three.js"></script>
<script>
// 接下來的代碼都與此位置做撰寫
</script>
</body>
</html>
簡單範例:
// 建立舞臺
const scene = new THREE.Scene()
// 建立相機
const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 )
// 建立渲染器
const renderer = new THREE.WebGLRenderer()
// 相機角度
camera.position.z = 500
// 將渲染器加入畫面
renderer.setSize( window.innerWidth, window.innerHeight )
document.body.appendChild( renderer.domElement )
// mesh 為我們後面要加入的 3D 模型
// 直接調用 scene 下的 add 方法,就可將 模型加入舞臺
scene.add( mesh )
// 將舞臺與相機加入渲染器
renderer.render( scene, camera )
Mesh
在上面的範例中,我們有提到將 Mesh
用 scene.add()
的方法加入舞臺中
那什麼是 Mesh 呢 ?
中文翻譯叫做 網面
, 呵呵 有說跟沒說一樣
為了在視窗中看見3D物件,我們一般利用 Geometry(幾何體) 和 Material(材質) 建構Mesh(網面),再將之加入場景中
可以把他想像為:
Geometry(幾何體) + Meterial(材質) = Mesh(網面)
或者可以那更直接的物體來理解
人體建模 + 白色皮膚 = 白人3D模型
人體建模 + 黑色皮膚 = 黑人3D模型
大概就是這個意思了
而最後產生出的 Mesh 就是我們要加入舞臺內的 3D 圖形了
一般都是使用 lender、3ds max、maya 等建模軟體建構 Geometry
好了理論就到此為止,現在我們使用 Three.js 提供的 方體 Geometry 與 Material 組成一個簡單的 mesh 在把他加在舞臺內
threejs 提供的 幾何圖形 :BoxBufferGeometry
// 建立舞臺
const scene = new THREE.Scene()
// 建立相機
const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 )
// 建立渲染器
const renderer = new THREE.WebGLRenderer()
// 相機角度
camera.position.z = 500
// 將渲染器加入畫面
renderer.setSize( window.innerWidth, window.innerHeight )
document.body.appendChild( renderer.domElement )
// mesh 為我們後面要加入的 3D 模型
// 直接調用 scene 下的 add 方法,就可將 模型加入舞臺
const geometry = new THREE.BoxBufferGeometry( 100, 100, 100 );
const material = new THREE.MeshBasicMaterial( {color: 0x00ff00} );
const mesh = new THREE.Mesh( geometry, material );
scene.add( mesh )
// 將舞臺與相機加入渲染器
renderer.render( scene, camera )
附上 CodePen 的 Demo:
以上就是對 Three.js 的簡單說明了,再來就要靠我們開發者自由發揮了
下列附上一些參考資料說明:
GitBook: Threejs 教學分享
IT幫忙鐵人賽: [Day1] WebGL 及 three.js 簡介
A-Frame
如果有稍微玩過一下 AR.js 用那 10 行 HTML 做出來的 Demo , 一定會有幾個疑問:
- 跟 這些沒看過的 HTML 的 Tag 是怎麼來的?
- 3D 圖形又是從哪裡跳出來的?
答案就是 A-Frame.js,他是一個基於 Three.js 產生的框架
如果有使用 Vue 的經驗,那就更容易理解, A-Frame 將 Three.js 的方法在進行一層的封裝,變成一個一個的 component ,在直接已 HTML 的方式進行調用
且可以支援幾乎全部的 Three.js 的屬性與方法
詳細使用的方式可以直接去參考 A-Frame 的官方網站
Aframe: 官網
補充
另外 在 AR.js 的專案中,作者很貼心的提供了 Three.js 與 A-Frame 兩種不同的 Example
且都有很細心的註解,建議可以從 basic.html
下手
會比較容易
另外在 Three.js 的目錄中,有個 experiments (實驗)
的目錄
裡面有很多 AR.js 相關的測試代碼
就連在前面提到的 Tracking.js 的臉部辨識,都有實際的 Demo 和 完整的註解 可以查看
真的很厲害!!