五一 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>
實現步驟
-
獲取渲染容器對象
var canvas = document.getElementById('renderCanvas');
-
加載渲染引擎
Engine 類負責低級別的 API 接口。第一個參數為渲染容器對象,第二個參數是開啟抗鋸齒。
var engine = new BABYLON.Engine(canvas, true);
-
加載場景
一個基本場景(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);
Arc Rotate Camera 示意圖
當然,上面的代碼可以封裝成一個方法。
-
注冊渲染循環
這些代碼非常重要,場景是需要循環渲染的。
engine.runRenderLoop(function () { scene.render(); });
-
實現容器自動縮放
window.addEventListener('resize', function () { engine.resize(); });
完整代碼與效果圖
效果圖
<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>
我的博客即將搬運同步至騰訊雲+社區,邀請大家一同入駐:https://cloud.tencent.com/developer/support-plan?invite_code=1r5oq0q418e9j