Web AR 入門: AR.js Tracking.js Three.js A-frame.js

WebAR 可拆分兩個部分相機與圖片識別3D模型

其實不名思義就是使用相機取得現實中的畫面作為背景,在藉由相當的 圖片辨識 的技術,在特定的座標位置,渲染出對應的 3D 模型,使使用者感受到與現實做連結,也就是 增强現實 (簡稱為 AR)

根據上面的敘述,我們可獨立分成兩個部分進行說明,這也是我個人在學習 Web AR 時,所得知的結論與紀錄

最廣受人知的 AR 範例:PokeMon GO

WebAR

  1. 取得攝像鏡頭畫面
  2. 圖片識別
  3. 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.jsArtoolkitThree.js 是處理 3D 繪圖的 JavaScript FrameWork, 這邊於 3D 圖形時,後面會做介紹,這邊先提 Artoolkit

Artoolkit

GitHub

ArtoolkitAR.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

在上面的範例中,我們有提到將 Meshscene.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:

See the Pen Three js example by SkyRoxas (@SkyRoxas) on CodePen.

以上就是對 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 和 完整的註解 可以查看

真的很厲害!!


參考連結: