Babylon.js基礎場景搭建
- 前言
- 最終實作效果
- 本文實作效果
- 技術選型
-
- 1.前端
- 2.後端
- 完整代碼
- 代碼分解
-
- 0.npm安裝相關依賴
- 1.引入子產品
- 2.場景初始化
- 3.ArcRotateCamera 相機初始化
- 4.燈光初始化
- 5.地面初始化
-
- 5-1. 綠地
- 5-2.網格地面
- 6.正方體物體初始化
- 7.天空盒初始化
- 後續計劃
-
- Babylon.js
- Blockly
- 開源項目GitHub連結
- 資源下載下傳連結
- 你的點贊是我繼續編寫的動力
前言
前段時間想要做一個web端的圖形化積木式程式設計(類似少兒程式設計)的案例,網上沖浪了一圈又一圈,終于技術選型好,然後代碼一頓敲,終于出來了一個雛形。
TIPS:該案例設計主要參考iRobot Coding,隻用做學習用途,侵删。
https://code.irobot.com/#/
最終實作效果
本文實作效果
- 可移動相機視角檢視3d模型
技術選型
1.前端
- vuetify - 基于vue的界面架構
- babylon.js - 3d圖形引擎
- ammo.js - 實體引擎庫
- blockly - 子產品化程式設計工具
2.後端
- ThinkJS - 基于Node.js的後端架構
完整代碼
- 一個完整的vue檔案
<template>
<div style="height: 100%;width: 100%;">
<div>
<canvas id="renderCanvas"></canvas>
</div>
</div>
</template>
<script>
import * as BABYLON from 'babylonjs';
import * as BABYLON_MATERAIAL from "babylonjs-materials"
function loadScene() {
//擷取到renderCanvas這個元素
var canvas = document.getElementById("renderCanvas");
//初始化引擎
var engine = new BABYLON.Engine(canvas, true);
//初始化場景
var scene = new BABYLON.Scene(engine);
//注冊一個渲染循環來重複渲染場景
engine.runRenderLoop(function () {
scene.render();
});
//浏覽器視窗變化時監聽
window.addEventListener("resize", function () {
engine.resize();
});
//相機初始化
var camera = new BABYLON.ArcRotateCamera("Camera", 0, 0, 5, new BABYLON.Vector3(0, 0, 10), scene);
camera.setPosition(new BABYLON.Vector3(20, 200, 400));
//相機角度限制
camera.upperBetaLimit = 1.5;//最大z軸旋轉角度差不多45度俯瞰
camera.lowerRadiusLimit = 50;//最小縮小比例
camera.upperRadiusLimit = 1500;//最大放大比例
//變焦速度
camera.wheelPrecision = 1; //電腦滾輪速度 越小靈敏度越高
camera.pinchPrecision = 20; //手機放大縮小速度 越小靈敏度越高
scene.activeCamera.panningSensibility = 100;//右鍵平移靈敏度
// 将相機和畫布關聯
camera.attachControl(canvas, true);
//燈光初始化
var light = new BABYLON.HemisphericLight("light1", new BABYLON.Vector3(0, 10, 0), scene);
//設定高光顔色
light.specular = new BABYLON.Color3(0, 0, 0);
//設定燈光強度
light.intensity = 1
// 綠地初始化
var materialPlane = new BABYLON.StandardMaterial("texturePlane", scene);
materialPlane.diffuseColor = new BABYLON.Color3(152 / 255.0, 209 / 255.0, 115 / 255.0)
materialPlane.backFaceCulling = false;
materialPlane.freeze()
var plane = BABYLON.MeshBuilder.CreateDisc("ground", {radius: 3000}, scene);
plane.rotation.x = Math.PI / 2;
plane.material = materialPlane;
plane.position.y = -0.1;
plane.freezeWorldMatrix()
//網格地闆初始化
const groundSide = 144;
var ground = BABYLON.Mesh.CreateGround("ground", groundSide, groundSide, 1, scene, true);
var groundMaterial = new BABYLON_MATERAIAL.GridMaterial("grid", scene);
groundMaterial.mainColor = BABYLON.Color3.White();//底闆顔色
groundMaterial.alpha = 1;//透明度
const gridLineGray = 0.95;
groundMaterial.lineColor = new BABYLON.Color3(gridLineGray, gridLineGray, gridLineGray);
groundMaterial.backFaceCulling = true; // 可看到背面
//大網格間距
groundMaterial.majorUnitFrequency = 16;
//小網格間距
groundMaterial.minorUnitVisibility = 0;
const gridOffset = 8; // 網格偏移量
groundMaterial.gridOffset = new BABYLON.Vector3(gridOffset, 0, gridOffset);
groundMaterial.freeze(); // 當機材質,優化渲染速度
ground.material = groundMaterial
ground.freezeWorldMatrix()
//正方形物體初始化
var blueBox = BABYLON.Mesh.CreateBox("blue", 10, scene);
var blueMat = new BABYLON.StandardMaterial("ground", scene);
blueMat.diffuseColor = new BABYLON.Color3(0.4, 0.4, 0.4);
blueMat.specularColor = new BABYLON.Color3(0.4, 0.4, 0.4);
blueMat.emissiveColor = BABYLON.Color3.Blue();
// blueMat.wireframe = true;//網格狀
blueBox.material = blueMat;
//起始位置坐标
blueBox.position.x = 0;
blueBox.position.y = 5;
blueBox.position.z = 0;
//天空盒初始化
var skyMaterial = new BABYLON_MATERAIAL.SkyMaterial("skyMaterial", scene);
skyMaterial.inclination = 0
skyMaterial.backFaceCulling = false;
var skybox = BABYLON.Mesh.CreateBox("skyBox", 5000.0, scene);
skybox.material = skyMaterial;
}
export default {
name: "test",
data() {
return {
}
},
mounted() {
//加載場景
loadScene()
},
}
</script>
<style scoped>
#renderCanvas {
width: 680px;
height: 680px;
touch-action: none;
z-index: 10000;
border-radius: 10px;
}
</style>
代碼分解
0.npm安裝相關依賴
npm install babylonjs babylonjs-gui babylonjs-loaders babylonjs-materials --save
- 安裝的子產品在package.json中生成
"dependencies": {
{
"babylonjs": "^4.2.0",//babylon核心庫
"babylonjs-gui": "^4.2.0",//UI界面庫(按鈕等)
"babylonjs-loaders": "^4.2.0",//開機加載庫(修改啟動動畫的)
"babylonjs-materials": "^4.2.0"//材質庫,有些材質像是SkyMaterial,babylonjs庫的預設材質中是沒有這個對象的
}
1.引入子產品
import * as BABYLON from 'babylonjs';
import * as BABYLON_MATERAIAL from "babylonjs-materials"
2.場景初始化
- template中
<div>
<canvas id="renderCanvas"></canvas>
</div>
- css中
#renderCanvas {
width: 680px;
height: 680px;
touch-action: none;
z-index: 10000;
border-radius: 10px;
}
- js中
//擷取到renderCanvas這個元素
var canvas = document.getElementById("renderCanvas");
//初始化引擎
var engine = new BABYLON.Engine(canvas, true);
//初始化場景
var scene = new BABYLON.Scene(engine);
//注冊一個渲染循環來重複渲染場景
engine.runRenderLoop(function () {
scene.render();
});
//浏覽器視窗變化時監聽
window.addEventListener("resize", function () {
engine.resize();
});
3.ArcRotateCamera 相機初始化
var camera = new BABYLON.ArcRotateCamera("Camera", 0, 0, 5, new BABYLON.Vector3(0,0,10), scene);
camera.setPosition(new BABYLON.Vector3(20, 200, 400));
//相機角度限制
camera.upperBetaLimit = 1.5;//最大z軸旋轉角度差不多45度俯瞰
camera.lowerRadiusLimit = 50;//最小縮小比例
camera.upperRadiusLimit = 1500;//最大放大比例
//變焦速度
camera.wheelPrecision = 1; //電腦滾輪速度 越小靈敏度越高
camera.pinchPrecision = 20; //手機放大縮小速度 越小靈敏度越高
scene.activeCamera.panningSensibility = 100;//右鍵平移靈敏度
// 将相機和畫布關聯
camera.attachControl(canvas, true);
4.燈光初始化
//設定半球光
var light = new BABYLON.HemisphericLight("light1", new BABYLON.Vector3(0, 10, 0), scene);
//設定高光顔色
light.specular = new BABYLON.Color3(0, 0, 0);
//設定燈光強度
light.intensity = 1
5.地面初始化
5-1. 綠地
// 添加地面
var materialPlane = new BABYLON.StandardMaterial("texturePlane", scene);
materialPlane.diffuseColor = new BABYLON.Color3(152 / 255.0, 209 / 255.0, 115 / 255.0)
materialPlane.backFaceCulling = false;//Allways show the front and the back of an element
materialPlane.freeze()
var plane = BABYLON.MeshBuilder.CreateDisc("ground", {radius: 6000}, scene);
plane.rotation.x = Math.PI / 2;
plane.material = materialPlane;
plane.position.y = -0.01;
plane.freezeWorldMatrix()
5-2.網格地面
//地闆
const groundSide = 144;
var ground = BABYLON.Mesh.CreateGround("ground", groundSide, groundSide, 1, scene, true);
var groundMaterial = new BABYLON_MATERAIAL.GridMaterial("grid", scene);
groundMaterial.freeze(); // Optimization.
groundMaterial.mainColor = BABYLON.Color3.White();//底闆顔色
groundMaterial.alpha = 1;//透明度
const gridLineGray = 0.95;
groundMaterial.lineColor = new BABYLON.Color3(gridLineGray, gridLineGray, gridLineGray);
groundMaterial.backFaceCulling = true; // Change this if the back of the pad needs to be visible.
//大網格間距
groundMaterial.majorUnitFrequency = 16;
//小網格間距
groundMaterial.minorUnitVisibility = 0;
const gridOffset = 0; // This makes the grid cells to be aligned with the pad's borders.
groundMaterial.gridOffset = new BABYLON.Vector3(gridOffset, 0, gridOffset);
ground.material = groundMaterial
ground.freezeWorldMatrix()
- TIPS:很多同學會發現,将兩個平面疊加時,移動相機視角,會出現蟲影現象
- 優化方案
//1、當機材質和模型
//綠地
//設定為靜态網格,freezeWorldMatrix之後,改變postion、rotation是無效的
plane.freezeWorldMatrix()
//将材質當機
plane.material.freeze()
//網格
ground.freezeWorldMatrix()
ground.material.freeze()
//2、增大兩個物體的y軸間距
plane.position.y = -0.1
6.正方體物體初始化
//添加物體
var blueBox = BABYLON.Mesh.CreateBox("blue", 10, scene);
var blueMat = new BABYLON.StandardMaterial("ground", scene);
blueMat.diffuseColor = new BABYLON.Color3(0.4, 0.4, 0.4);
blueMat.specularColor = new BABYLON.Color3(0.4, 0.4, 0.4);
blueMat.emissiveColor = BABYLON.Color3.Blue();
// blueMat.wireframe = true;//網格狀
blueBox.material = blueMat;
//起始位置坐标
blueBox.position.x = 0;
blueBox.position.y = 5;
blueBox.position.z = 0;
7.天空盒初始化
//天空盒初始化
var skyMaterial = new BABYLON_MATERAIAL.SkyMaterial("skyMaterial", scene);
skyMaterial.inclination = 0
skyMaterial.backFaceCulling = false;
var skybox = BABYLON.Mesh.CreateBox("skyBox", 5000.0, scene);
skybox.material = skyMaterial;
後續計劃
Babylon.js
- 加載網絡模型
- 點選移動物體
- 自定義啟動界面
- 初始化錄影機動畫
- 物體重力效果
- babylonjs-gui 按鈕實作
- babylonjs+ammojs 碰撞體實作
- 将3d界面放入可拖動視窗中
Blockly
- 入門使用blockly
- 自定義block塊
- blockly第三方元件使用
- 接入js-interpreter,步驟運作block塊
- …(想到啥寫啥)
開源項目GitHub連結
https://github.com/Wenbile/Child-Programming-Web
資源下載下傳連結
- Vue前端源碼
- ThinkJS後端源碼