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

淘朗英發表於2016-12-07

緊接上文

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抓貓貓一樣,會動會跳,還會發紅包。


相關文章