天天看點

使用 Babylon.js 在 HTML 頁面加載 3D 對象

五一 Windwos Blogs 推了一篇部落格, Babylon.js v3.2 釋出了。因為一直有想要在自己部落格上加載 3D 對象的沖動,這兩天正好看到了,就動手研究研究。本人之前也并沒有接觸過 WebGL ,這方面算是知識盲區,需求完成之後感覺非常炫酷,順手寫篇部落格記錄下來。不得不說 3D 列印和 VR 慢慢的開始走進平時的生活了,技術的成熟與硬體成本的變低,結合内容跨平台共享與各種簡單的 js 架構, WebGL 和 WebVR 很可能就是未來 Web 方向的主流技術。期待美好而炫酷的未來ing

Babylon.js 是什麼

Babylon.js 是一個 JavaScript 開源架構,可以在浏覽器或 Web 應用程式中簡單便捷的建構 3D 遊戲和 WebGL、WebVR 等 3D 體驗。Babylon.js 非常強大,強大到可以去建構商業遊戲。畢竟我才花了兩天時間去了解它,隻用來加載 3D 對象确實是大材小用了,文檔和 GitHub 位址在下面。

Babylon GitHub :

https://github.com/BabylonJS/Babylon.js

Babylon Document :

https://doc.babylonjs.com/

基本代碼

Babylon.js 并不是所有的 3D 對象都支援,支援的類型: .glTF 、 .obj 、 .stl 、 .babylon 。

這裡以 STL 對象為例,首先需要引入兩個 js 檔案。一個是 Babylon.js ,另一個是 STL Loader, js 檔案在 GitHub 中自行搜尋下載下傳引入。

<script src="~/js/babylon.js"></script>
<script src="~/js/babylon.stlFileLoader.min.js"></script>           

同時還需要一個 HTML5 的 canvas 标簽作為 Babylon.js 的渲染容器

<canvas id="renderCanvas" style="width:100%;height:100%;touch-action:none;"></canvas>           

緊接着注冊一個 DOM 事件,我們的渲染代碼将在事件裡完成,以確定執行渲染之前加載整個 DOM 。

<script>
    window.addEventListener('DOMContentLoaded', function() {
        // TODO
    });
</script>           

實作步驟

  1. 擷取渲染容器對象
    var canvas = document.getElementById('renderCanvas');           
  2. 加載渲染引擎 Engine 類負責低級别的 API 接口。第一個參數為渲染容器對象,第二個參數是開啟抗鋸齒。
    var engine = new BABYLON.Engine(canvas, true);           
  3. 加載場景

    一個基本場景(

    Scene )裡需要包括相機( Cameras )、光源( Lights )、3D 對象。這裡相機使用 ArcRotateCamera ,滑鼠可以控制旋轉和縮放。光源使用 HemisphericLight 半球光,用來模拟現實中的環境光。當然你也可以使用其他相機和光源,文檔連結已給出。
    // 基本的場景對象
    var scene = new BABYLON.Scene(engine);
    
    // 半球光對象,朝向天空
    var light = new BABYLON.HemisphericLight('light1', new BABYLON.Vector3(0, 1, 0), scene);
    
    // 弧度旋轉相機,參數含義為:α角度、β角度、半徑、目标方向、場景對象。
    // 下圖非常詳細的說明了各個參數的真實場景的含義
    var camera = new BABYLON.ArcRotateCamera('camera1', 0, 0, 10, new BABYLON.Vector3(40, 40, 40), scene);
    // 相機設定在原點位置
    camera.setTarget(BABYLON.Vector3.Zero());
    // 把相機附在渲染對象上
    camera.attachControl(canvas, false);
    
    // 把 STL 對象附加在現有的場景對象上
    // 可以從檔案夾中選取對象,也可以給出一個 URL
    BABYLON.SceneLoader.Append("../", "Chariot_Red_f.stl", scene);           
![1](https://yqfile.alicdn.com/ff360ea3b954ca25c7b7a99bccef8ee2a17da18b.jpeg)
<p style="text-align:center;margin-bottom:25px;color:gray"><small>Arc Rotate Camera 示意圖</small></p>

當然,上面的代碼可以封裝成一個方法。
           
  1. 注冊渲染循環
    這些代碼非常重要,場景是需要循環渲染的。
               
    engine.runRenderLoop(function () {
        scene.render();
    });           
  2. 實作容器自動縮放
    window.addEventListener('resize', function () {
        engine.resize();
    });           

完整代碼與效果圖

使用 Babylon.js 在 HTML 頁面加載 3D 對象

效果圖

<canvas id="renderCanvas" style="width:100%;height:100%;touch-action:none;"></canvas>

<script src="~/js/babylon.js"></script>
<script src="~/js/babylon.stlFileLoader.min.js"></script>
<script>
    window.addEventListener('DOMContentLoaded', function () {
        var canvas = document.getElementById('renderCanvas');
        var engine = new BABYLON.Engine(canvas, true);

        var scene = new BABYLON.Scene(engine);
        var camera = new BABYLON.ArcRotateCamera('camera1', 0, 0, 10, new BABYLON.Vector3(40, 40, 40), scene);
        camera.setTarget(BABYLON.Vector3.Zero());
        camera.attachControl(canvas, false);
        var light = new BABYLON.HemisphericLight('light1', new BABYLON.Vector3(0, 1, 0), scene);

        BABYLON.SceneLoader.Append("", "@Model.PreviewModel", scene);

        engine.runRenderLoop(function () {
            scene.render();
        });

        window.addEventListener('resize', function () {
            engine.resize();
        });
    });
</script>           

繼續閱讀