###### tags: `babylon`
# Babylon最佳化
---
[TOC]
---
## 載入最佳化
### 模型壓縮
1. 以外觀可接受的程度來決定面數可以少到何種程度。
2. 使用壓縮比高的模型格式GLTF。
3. [glTF Draco壓縮工具](https://google.github.io/draco/),具有壓縮與解壓功能,壓縮後的大小為原來的十分之一。
4. [glTF Pipeline壓縮工具](https://github.com/CesiumGS/gltf-pipeline),整合Draco壓縮功能,可產生Draco壓縮後的glTF檔,也可將glTF檔轉為glb檔。
以下為glTF Pipeline範例,-d代表使用draco壓縮,-t代表將貼圖分離出來:
```cmake=
gltf-pipeline -i model.gltf -o modelDraco.gltf -d -t
```
以下為Babylon讀取draco壓縮模型範例:
```javascript=
var delayCreateScene = function () {
var scene = new BABYLON.Scene(engine);
scene.useRightHandedSystem = true;
BABYLON.Tools.LoadFile("https://osense.azurewebsites.net/test/BarramundiFish.bin", async function (data) {
var dracoCompression = new BABYLON.DracoCompression();
var attributes = {
// [BABYLON.VertexBuffer.UVKind]: 0,
// [BABYLON.VertexBuffer.NormalKind]: 1,
// [BABYLON.VertexBuffer.TangentKind]: 2,
[BABYLON.VertexBuffer.PositionKind]: 3
};
var vertexData = await dracoCompression.decodeMeshAsync(data, attributes);
var mesh = new BABYLON.Mesh("dracoMesh", scene);
var geometry = new BABYLON.Geometry("dracoGeometry", scene, vertexData, undefined, mesh);
mesh.material = new BABYLON.PBRMaterial("material", scene);
mesh.material.sideOrientation = BABYLON.Material.CounterClockWiseSideOrientation;
mesh.material.metallic = 0;
scene.createDefaultCameraOrLight(true, undefined, true);
}, undefined, undefined, true);
return scene;
};
```
### 貼圖壓縮
1. 使用2的n次冪尺寸。
2. 除了環景圖為了畫質需要4K外,其餘貼圖不應超過1024,除非有需要近看,而因畫質不足才上2048。
3. 無透明貼圖請使用jpg檔,需要透明的貼圖才使用png檔。
4. [Basis Universal壓縮工具](https://github.com/BinomialLLC/basis_universal),將png檔轉換為basis文件後大小相當於jpg檔,basis文件可以再透過轉碼器轉換為各種設備上能使用的壓縮紋理(ETC1/ETC2/PVRTC1/ASTC/EC1-5/BC7),但不支援需半透明的圖檔。
5. [線上Basis文件轉換測試](http://binomial.biz/webgl/encode_test/)
以下為讀取basis圖檔文件範例:
```javascript=
var createScene = function() {
// Scene setup
var scene = new BABYLON.Scene(engine);
scene.environmentTexture = BABYLON.CubeTexture.CreateFromPrefilteredData("textures/environment.env", scene);
var camera = new BABYLON.ArcRotateCamera("Camera", 3 * Math.PI / 2, Math.PI / 2, 60, BABYLON.Vector3.Zero(), scene);
camera.attachControl(canvas, false);
var light = new BABYLON.HemisphericLight("light1", new BABYLON.Vector3(0, 1, 0), scene);
light.intensity = 0.7;
// Create material from image with alpha
var mat = new BABYLON.PBRMaterial("dog", scene);
mat.metallic = 0;
mat.roughness = 0;
mat.albedoTexture = new BABYLON.Texture("https://3dvp-dev.s3.eu-west-2.amazonaws.com/test.basis", scene);
// Apply material to a box
var box = BABYLON.MeshBuilder.CreateBox("box", {size: 30}, scene);
box.scaling.x = 768/512
box.material = mat;
return scene;
};
```
### 檔案gzip壓縮傳輸
在Server端開啟gzip壓縮,可使檔案變小、傳輸量降低、等待時間變短。
### 快取載入
1. 使用CDN服務加速文件下載速度。
2. 使用indexDB快取載入,首次快取載入之後提升載入速度。
## 渲染最佳化
### 剔除(Culling)
剔除分為三種:視錐體剔除、背面渲染剔除、遮擋剔除。
- 視錐體剔除:物件不在攝影機視角範圍內就不去渲染它。
- 背面渲染剔除:物件的背面因為看不到,所以不去渲染它。
- 遮擋剔除:物件被其他物件遮擋看不到而不去渲染它。
在場景中被被剔除的物件不去渲染,進而提高CPU、GPU運作效能,Babylon提供以下剔除策略:
```javascript=
/**
* Possible values :
* - BABYLON.AbstractMesh.CULLINGSTRATEGY_STANDARD
* - BABYLON.AbstractMesh.CULLINGSTRATEGY_BOUNDINGSPHERE_ONLY
* - BABYLON.AbstractMesh.CULLINGSTRATEGY_OPTIMISTIC_INCLUSION
* - BABYLON.AbstractMesh.CULLINGSTRATEGY_OPTIMISTIC_INCLUSION_THEN_BSPHERE_ONLY
*/
mesh.cullingStrategy = oneOfThePossibleValues;
```
### LOD
[層級細節](https://doc.babylonjs.com/divingDeeper/mesh/simplifyingMeshes),當模型離攝影機越遠,簡化模型網格以降低細節呈現來提高渲染效能,以下為範例:
```javascript=
BABYLON.SceneLoader.ImportMesh("", "./", "DanceMoves.babylon", scene, (newMeshes, particleSystems, skeletons) => {
newMeshes[1].simplify(
[
{ quality: 0.9, distance: 25 },
{ quality: 0.3, distance: 50 },
],
false,
BABYLON.SimplificationType.QUADRATIC,
function () {
alert("LOD finisehd, let's have a beer!");
},
);
});
```
## 參考資料
:::info
[模型與貼圖壓縮分析比較](https://isux.tencent.com/articles/isux-optimizing-3d-model.html)
[Babylon官方最佳化文件](https://doc.babylonjs.com/divingDeeper/scene/optimize_your_scene)
[官方Basis file format說明](https://doc.babylonjs.com/advanced_topics/mutliPlatTextures#basis-file-format)
[Basis Universal Texture技術介紹](https://www.khronos.org/blog/google-and-binomial-contribute-basis-universal-texture-format-to-khronos-gltf-3d-transmission-open-standard)
[官方DracoCompression API說明](https://doc.babylonjs.com/typedoc/classes/babylon.dracocompression)
[官方BasisTools說明](https://doc.babylonjs.com/typedoc/classes/babylon.basistools)
:::
## Basis壓縮自動化參考資料
:::info
[即時圖片預覽](https://www.javascripture.com/FileReader)
[XMLHttpRequest範例1](http://www.henryalgus.com/reading-binary-files-using-jquery-ajax/)
[XMLHttpRequest範例2](https://www.html5rocks.com/zh/tutorials/file/xhr2/)
[JPG to PNG](http://www.fly63.com/article/detial/511)
[Canvas型態轉換1](https://blog.csdn.net/yinwhm12/article/details/73482904)
[Canvas型態轉換2](https://chiayilai.com/image-%E5%90%84%E7%A8%AE%E5%9E%8B%E6%85%8B%E8%BD%89%E6%8F%9Bblob-dataurl-canvas-in-javascript/)
[Canvas資料上傳](https://www.itread01.com/content/1549139611.html)
:::