【溫故知新】——BABYLON.js學習之路·前輩經驗(一)

前言:公司用BABYLON做爲主要的前端引擎,同事們在長時間的項目實踐中摸索到有關BABYLON的學習路徑和問題解決方法,這裏只做爲溫故知新。前端


 

1、快速學習BABYLON



1. 閱讀Babylon[基礎教程](http://doc.babylonjs.com/babylon101/)

2. 閱讀[一些BABYLON的新特性](http://doc.babylonjs.com/features/)
3. 閱讀[代碼片斷](http://doc.babylonjs.com/samples)
4. 一些[更深刻的教程詳解](http://doc.babylonjs.com/how_to/)
5. [在遊樂場玩耍](http://doc.babylonjs.com/playground/)


2、須要掌握的基本技能



1. engine,scene等建立,抗鋸齒,像素比,深度緩衝區等配置項

2. 燈光的建立,基本屬性,做用域
3. 相機的建立,基本屬性,多相機的切換,綁定等
4. 材質的建立,不一樣紋理類型等
5. 場景中的元素,霧化,天空盒,陰影,地形圖,世界座標系,本地座標系等
6. 事件,actionManager,onPointerDownObservable,pick,pickWithRay,
onViewMatrixChangedObservable,onLightRemovedObservable等基本事件

7. UI

3、項目開發中遇到的一些問題及重點功能



# 燈光
//設置做用物體
light.includedOnlyMeshes //設置排除物體
light.excludedMeshes
# 相機
一、相機多個動畫的正確順序
targetScreenOffet->target->beta->alpha->radius
二、相機運動觸發的事件 
camera.onViewMatrixChangedObservable
三、漫遊相機定製跳躍轉向碰撞等功能
//有兩種方法能夠根據世界矢量進行碰撞位移
//1.
camera._collideWithWorld(camera.getFrontPosition(10).subtract(camera.position)) //2.
camera.cameraDirection.addInPlace(camera._transformedDirection); //如跳躍,則相對世界向上
scene.activeCamera.cameraDirection.addInPlace(new BABYLON.Vector3(0, 4, 0)); //重力回到地面
camera._needMoveForGravity = true; //定製位移方向
var speedXX=camera._computeLocalCameraSpeed()*(左右慣性因子*panel) var speed=camera._computeLocalCameraSpeed()*(先後慣性因子*panel) camera._localDirection.copyFromFloats(speedX, 0, speedZ); camera.getViewMatrix().invertToRef(camera._cameraTransformMatrix); BABYLON.Vector3.TransformNormalToRef(camera._localDirection, camera._cameraTransformMatrix, camera._transformedDirection); camera.cameraDirection.addInPlace(camera._transformedDirection);
//定製旋轉方向 camera.rotation.x=(beta慣性因子*panel) camera.rotation.y=(alpha慣性因子*panel)
 
# 重力
//添加劇力
scene.gravity = new BABYLON.Vector3(0, -9.81, 0); camera.applyGravity = true; //添加碰撞
scene.collisionsEnabled = true; camera.checkCollisions = true; ground.checkCollisions = true; box.checkCollisions = true; //相機碰撞橢圓體
camera.ellipsoid = new BABYLON.Vector3(.5, 1, .5); //arcRotateCamera的碰撞橢圓體
camera.collisionRadius =new BABYLON.Vector3(0.5, 0.5, 0.5) //防止向上跳後沒法落地
camera._needMoveForGravity = true; //物體碰撞
mesh.moveWithCollisions(vec3); //使用webworker運行碰撞檢測
scene.workerCollisions = true|false
 
## 第二視圖
var camera = new BABYLON.ArcRotateCamera("Camera", 0, 0, 0, BABYLON.Vector3.Zero(), scene); camera.setPosition();
var followCamera = new BABYLON.FollowCamera("follow", new BABYLON.Vector3(400, 500, 1000), scene, ground) followCamera.radius = 0 followCamera.heightOffset = 400; scene.activeCameras.push(followCamera); scene.activeCameras.push(camera);
followCamera.viewport
= new BABYLON.Viewport(0, 0, 0.3, 0.3) camera.viewport = new BABYLON.Viewport(0, 0.3, 1, 0.7)
 
## 四元數轉換爲歐拉角
sphere2.lookAt(sphere.position) camera.position=sphere2.position; camera.rotation.x=-sphere2.rotationQuaternion.toEulerAngles().x; camera.rotation.y=sphere2.rotationQuaternion.toEulerAngles().y+Math.PI; camera.rotation.z=sphere2.rotationQuaternion.toEulerAngles().z;

## 漫遊相機和旋轉相機的轉換
  • 旋轉相機 -> 漫遊相機
    var radiusv3 = pickInfo.pickedPoint var radius = radiusv3.length(); var alpha = Math.acos(radiusv3.x / Math.sqrt(Math.pow(radiusv3.x, 2) + Math.pow(radiusv3.z, 2))); if (radiusv3.z < 0) { alpha = 2 * Math.PI - alpha; } var beta = Math.acos(radiusv3.y / radius);
  • 漫遊相機-> 旋轉相機
    var radiusv3 = zxz.camera2.position;
    var radius = radiusv3.length();
    var alpha = Math.acos(radiusv3.x / Math.sqrt(Math.pow(radiusv3.x, 2) + Math.pow(radiusv3.z, 2)));
    if (radiusv3.z < 0) {
        alpha = 2 * Math.PI - alpha;
    }
    var beta = Math.acos(radiusv3.y / radius);

     

# 材質

一、材質特殊參數web

material.maxSimultaneousLights //最多可接受燈光個數,默認4個 material.useLogarithmicDepth material.needDepthPrePass //深度判斷 material.transparencyMode=2;

二、 dynamicTexturecanvas

var dynamicTexture = new BABYLON.DynamicTexture("DynamicTexture", {width:50,height:50}, scene, true); dynamicTexture.hasAlpha = true; dynamicTexture.drawText(text, 10, 50, "bold 100px Arial", color , "transparent", true,true);
var plane = new BABYLON.Mesh.CreatePlane("TextPlane", size, scene, true); plane.material = new BABYLON.StandardMaterial("TextPlaneMaterial", scene); plane.material.backFaceCulling = false; plane.material.specularColor = new BABYLON.Color3(0, 0, 0); plane.material.diffuseTexture = dynamicTexture;

三、鏡面反射材質數組

Material.diffuseColor = new BABYLON.Color3(0.4, 0.4, 0.4); Material.reflectionTexture = new BABYLON.MirrorTexture("mirror", 1024, scene, true); //Create a mirror texture
Material.reflectionTexture.mirrorPlane = new BABYLON.Plane(0, -1.0, 0, -10.0); Material.reflectionTexture.renderList = [ground,skybox]; Material.reflectionTexture.level = 0.6;//Select the level (0.0 > 1.0) of the reflection

四、 探針app

var box = BABYLON.Mesh.CreateBox("box", 5000, scene); //直接貼反射貼圖 //material.reflectionTexture = new BABYLON.CubeTexture('img/bg/4', scene); //box.material = new BABYLON.StandardMaterial("boxMaterial", scene); //box.material.reflectionTexture = new BABYLON.CubeTexture('img/bg/4', scene); //box.material.reflectionTexture.coordinatesMode = BABYLON.Texture.SKYBOX_MODE; //box.material.backFaceCulling = false; //box.rotation.z = Math.PI / 2;

var probe = new BABYLON.ReflectionProbe("main", 512, scene); probe.renderList.push(yellowSphere); probe.renderList.push(greenSphere); probe.renderList.push(blueSphere); probe.renderList.push(mirror); mainMaterial.diffuseColor = new BABYLON.Color3(1, 0.5, 0.5); mainMaterial.reflectionTexture = probe.cubeTexture; mainMaterial.reflectionFresnelParameters = new BABYLON.FresnelParameters(); mainMaterial.reflectionFresnelParameters.bias = 0.02;

五、 菲涅爾ide

//全部菲涅爾類型
StandardMaterial.diffuseFresnelParameters StandardMaterial.reflectionFresnelParameters StandardMaterial.opacityFresnelParameters StandardMaterial.emissiveFresnelParameters StandardMaterial.refractionFresnelParameters //用法
var saturne = BABYLON.Mesh.CreateSphere("saturne", 16, 80, scene); var saturne_material = new BABYLON.StandardMaterial("saturne_material", scene); saturne_material.reflectionTexture = new BABYLON.CubeTexture("../../assets/skybox/nebula", scene); saturne_material.reflectionFresnelParameters = new BABYLON.FresnelParameters(); saturne_material.reflectionFresnelParameters.bias = 0.2; saturne_material.emissiveFresnelParameters = new BABYLON.FresnelParameters(); saturne_material.emissiveFresnelParameters.bias = 0.6; saturne_material.emissiveFresnelParameters.power = 4; saturne_material.emissiveFresnelParameters.leftColor = BABYLON.Color3.White(); saturne_material.emissiveFresnelParameters.rightColor = new BABYLON.Color3(0.6, 0.6, 0.6); saturne.material = saturne_material;

 

# 動畫
1. 建立animation對象函數

var animation = new BABYLON.Animation(name, targetProperty, framePerSecond, dataType, loopMode, enableBlending);

2. 綁定鍵值對oop

animation.setKeys([{frame:0,value:0},...])

3. 設置運動函數post

var bezierEase = new BABYLON.BezierCurveEase(.97, .2, 0, .58); bezierEase.setEasingMode(BABYLON.EasingFunction.EASINGMODE_EASEOUT); animation.setEasingFunction(bezierEase);

4. 將動畫對象push到mesh的animations屬性中
學習

mesh.parent.animations.push(animationPosition);

5. 開始運行動畫

var animatable=beginAnimation(target, from, to, loop, speedRatio, onAnimationEnd, animatable) animatable.pause() //暫停
animatable.restart() //從暫停的地方開始播放
animatable.stop()    //中止動畫,不能恢復
animatable.reset()   //從新開始,從0 frame的地方,無論循環模式

** 注意:
* bug :從0到0 整個場景會抖動
* 由3Dmax導入動畫,直接開始運行,bug:若是scene.stopAnimation,下次begin必定要經過事件才能正常觸發。
* 就算沒有給對象設置動畫對象,可是開始運行動畫了,也能經過scene.getAnimatableByTarget(mesh)獲取到animatable對象(雖然animations爲空數組)
* 若是loop 設置爲了ture,那麼根據loopMode來進行循環,而且永遠處於運動狀態,不會觸發onAnimationEnd回調函數,除非stopAnimation或者再運行一遍beginAnimation,
或者使用 BABYLON.Animation.CreateAndStartAnimation(且使用ANIMATIONLOOPMODE_CONSTANT模式)
* 若是loop設置爲false,動畫只執行一次,而後觸發onAnimationEnd回調函數
* 在動畫運行過程當中若是手動更新了animation.setKeys(),那麼繼續當前的動畫且currentFrame不變,可是更新了keys,也就是跳到了新的keys的當前frame畫面,因此會有一個突變的卡頓現象
* 若是當前處於運動狀態,又運行了一遍beginAnimation,那麼會stopAnimation,並重置當前幀數,能夠解決卡頓現象。
* animatable.stop直接中止運動狀態,restart結束暫停狀態,不會變化位置,若是stop等中止了運動狀態,restart無效,reset是直接回到動畫剛開始的位置
* createAndStartAnimation不會打斷其餘動畫,可是beginAnimation會打斷全部animation包括createAndStartAnimation
* beginAnimation會打斷createAndStartAnimation,createAndStartAnimation不會打斷beginAnimation

# 粒子

1、發射方向類型 particleSystem.particleEmitterType = new BABYLON.SphereParticleEmitter(10,false); //或者
particleSystem.createSphereEmitter(10);//GPUParticle沒有這個API

2、子粒子,放煙花 particleSystem.subEmitters = [particleSystem,..]
三、members particleSystem.disposeOnStop
=true;

 

# mesh
一、facet Data

//得到三角形的中心
mesh.getFacetPosition(faceId) //the 50th facet local position
var localPositions = mesh.getFacetLocalPositions(); // returns the array of facet positions in the local space
var localPos = localPositions[50]; //normal
var norm = mesh.getFacetNormal(faceId); // var localNormals = mesh.getFacetLocalNormals(); // returns the array of facet normals in the local space
var localPos = localNormals[50]; // Vector3 : the 50th facet local position

//All the methods dealing with the world coordinates use the mesh world matrix. As you may know, this matrix is automatically computed on the render call.
If you've just moved, scaled or rotated your mesh before calling the facetData methods using the world values and you're not sure about this, you can ever force the world matrix computation. mesh.rotate.y += 0.2; // the mesh will be rotated on the next render call, but I need a rotated normal
mesh.computeWorldMatrix(true); // force the world matrix computation
var norm = mesh.getFacetNormal(50); // returns the world normal of the mesh 50th facet

二、 獲取軸心

//若是以前有freeze矩陣,則須要先從新計算
mesh.computeWorldMatrix(true) mesh.getAbsolutePivotPoint()

三、設置自己軸誤差

mesh.setPivotPoint(vec3)

四、畫線

var lines=new BABYLON.Mesh.CreateLines("line",[v0,v1,v2,v3],scene) //畫線默認是以gl.LINES方法繪畫,例子中雖然只傳入了4個頂點,可是默認0,1 1,2 2,3  //顏色:lines.color

五、自定義geometry

//簡單的使用verticesData
mesh.setVerticesData(kind:string,data:array,updatable:boolean,stride:number) //demo:
mesh.setVerticesData("position", positions, true) //stride :position,normal 默認3,uv 默認2 //或者使用buffer,能夠更多的配置offset,size,stride等選項
mesh.setVerticesBuffer(new vertexBuffer(engine,data:array,kind:string,updatable:boolean,postponeInternalCreation:boolean,stride:number,instanced:Boolean,offset:number,size:number)) //demo:
var aRotation = new Float32Array(pointLength*2); mesh.setVerticesBuffer(new BABYLON.VertexBuffer(engine, aRotation, "aRotation", true, false, 2)); //最後必須設置索引
mesh.setIndices(Array)

六、使用自定義的attribute傳入着色器

var material = new BABYLON.ShaderMaterial("particle", scene, "./js/particle", { uniforms: ["worldViewProjection", "uTime", "uTranslation", "axis", "alpha", /*"resolution",*/ "pointSize", "baseColor", /*"rebuilding",*/ "status", "scatter", "uvMode", "mobile"], attributes: ["position", "uv", "aRotation", "aAnimation", "raxis"], needAlphaBlending:true //經過material.alphaMode=來設置混合模式
}); material.fillMode = 2; material.setFloat("uTime", 0.); material.setVector3("axis", new BABYLON.Vector3(0, 1, 0)); material.setVector3("uTranslation", new BABYLON.Vector3(0, 500, 0)); material.setColor3("baseColor", new BABYLON.Color3(1, 1, 1)); material.setFloat("status", .5); material.setFloat("scatter", 0); material.setFloat("uvMode", 0); 

七、通常用到的建立着色器程序的兩種方法

BABYLON.Effect.ShadersStore["customVertexShader"]= "\r\n"+
"precision highp float;\r\n"+

"attribute vec3 position;\r\n"+
"attribute vec2 uv;\r\n"+

"uniform mat4 worldViewProjection;\r\n"+

"varying vec2 vUV;\r\n"+

"void main(void) {\r\n"+
" gl_Position = worldViewProjection * vec4(position, 1.0);\r\n"+

" vUV = uv;\r\n"+
"}\r\n";

BABYLON.Effect.ShadersStore["customFragmentShader"]= "\r\n"+
"precision highp float;\r\n"+

"varying vec2 vUV;\r\n"+

"uniform sampler2D textureSampler;\r\n"+

"void main(void) {\r\n"+
" gl_FragColor = texture2D(textureSampler, vUV);\r\n"+
"}\r\n";


//----------------------------------------------------------------------
var shaderMaterial = new BABYLON.ShaderMaterial("shader", scene, {
vertex: "custom",
fragment: "custom",
},
{
attributes: ["position", "normal", "uv"],
uniforms: ["world", "worldView", "worldViewProjection", "view", "projection"]
});

var mainTexture = new BABYLON.Texture("amiga.jpg", scene);
shaderMaterial.setTexture("textureSampler", mainTexture);
View Code
//方法一. BABYLON.Effect.ShadersStore["customVertexShader"]
var shaderMaterial = new BABYLON.ShaderMaterial("shader", scene, { vertex: "custom", fragment: "custom", }, { attributes: ["position", "normal", "uv"], uniforms: ["world", "worldView", "worldViewProjection", "view", "projection"] });
//方法二.建立單獨的文件basename.vertex.fx和basename.fragment.fx
var cloudMaterial = new BABYLON.ShaderMaterial("cloud", scene, "./basename", { attributes: ["position", "uv"], uniforms: ["worldViewProjection"], needAlphaBlending:true //經過material.alphaMode=來設置混合模式
});

 

## 傳參方法

setTexture,setFloat,setFloats,setColor3,setColor4,setVector2,setVector3,setVector4,setMatrix attributes: mesh.setVerticesBuffer(new BABYLON.VertexBuffer(engine, aRotation, "aRotation", true, false, 2));

## BABYLON默認傳入的參數

一、自動傳入的uniform變量

world,
view,
projection,
worldView,
worldViewProjection
cameraPosition

二、自動傳入的attribute變量

position
normal
uv
uv2

## 經過索引建立submesh

BABYLON.SubMesh.CreateFromIndices(subMesh.materialIndex, offset, Math.min(subdivisionSize, totalIndices - offset), mesh);

## CSG

union 相加 subtract 相減` intersect 相交
var sphereCSG = BABYLON.CSG.FromMesh(sphere); sphereCSG.subtractInPlace(BABYLON.CSG.FromMesh(cylinderMesh)); sphereCSG.toMesh("bowling ball", sphere.material, scene, false
); copyTransformAttributes(csg)

默認是源CSG的變換矩陣,若是須要改變,好比intersect的CSG,那麼能夠設置相交部分的CSG爲變換矩陣,軸就在新建物體的原點

## polygonMeshBuilder
經過path2建立的polygon是動態建立的,會根據scaling來增長頂點


# 場景
一、本身建立天空盒

var skybox = BABYLON.Mesh.CreateBox("skyBox", 100.0, scene); var skyboxMaterial = new BABYLON.StandardMaterial("skyBox", scene); skyboxMaterial.backFaceCulling = false; skyboxMaterial.reflectionTexture = new BABYLON.CubeTexture("../../Assets/skybox/skybox", scene); skyboxMaterial.reflectionTexture.coordinatesMode = BABYLON.Texture.SKYBOX_MODE; skyboxMaterial.diffuseColor = new BABYLON.Color3(0, 0, 0); skyboxMaterial.specularColor = new BABYLON.Color3(0, 0, 0); skybox.material = skyboxMaterial; skybox.material.disableLighting = true; skybox.infiniteDistance = true;
//天空盒模糊 skyMaterial.roughness = 6;

二、利用API建立場景天空盒,將做用於場景中全部的物體

scene.environmentTexture=new BABYLON.CubeTexture("/assets/textures/SpecularHDR-env.dds"); var envTexture = new BABYLON.CubeTexture("/assets/textures/SpecularHDR.dds", scene); scene.createDefaultSkybox(envTexture, pbr?:boolean, scale?:number,blur?:number);

三、利用API生成默認場景

var helper=scene.createDefaultEnvironment(opt); helper.setMainColor(BABYLON.Color3.Teal());
opt: createGround: Specifies wether or not to create a ground. groundSize: Specifies the ground size (
if sizeAuto is false). groundTexture: The texture used on the ground (Default to Babylon CDN). groundColor: The color mixed in the ground texture by default. enableGroundShadow: Enables the ground to receive shadows. groundShadowLevel: Helps preventing the shadow to be fully black on the ground. enableGroundMirror: Creates a mirror texture attach to the ground. createSkybox: Specifies wether or not to create a skybox. skyboxSize: Specifies the skybox size (if sizeAuto is false). skyboxTexture: The texture used on the skybox (Default to Babylon CDN). skyboxColor: The color mixed in the skybox texture by default. sizeAuto: Compute automatically the size of the elements to best fit with the scene. setupImageProcessing: Sets up the inmage processing in the scene. environmentTexture: The texture used as your environment texture in the scene (Default to Babylon CDN). cameraExposure: The value of the exposure to apply to the scene. cameraContrast: The value of the contrast to apply to the scene. toneMappingEnabled: Specifies wether or not tonemapping should be enabled in the scene.

## 霧化

scene.fogMode = BABYLON.Scene.FOGMODE_EXP; scene.fogDensity = 0.02; scene.fogColor = scene.clearColor; material.fogEnabled;

## 地形圖

BABYLON.Mesh.CreateGroundFromHeightMap("ground", "worldHeightMap.jpg", width:200, height:200, subdivision:250, minHeight:0, maxHeight:10, scene, updatable:false, onReady:successCallback); getHeightAtCoordinates(x,z)

## 陰影

var shadowGenerator=new BABYLON.ShadowGenerator(陰影貼圖的大小:1024,light); //產生陰影的物體列表
shadowGenerator.getShadowMap().renderList.push(box); //軟化陰影 //泊松抽樣
shadowGenerator.usePoissonSampling = true; //指數陰影貼圖
shadowGenerator.useExponentialShadowMap = true; shadowGenerator.depthScale=50
//模糊指數陰影圖
shadowGenerator.useBlurExponentialShadowMap = true; //模糊質量
shadowGenerator.useKernelBlur = true; shadowGenerator.blurScale = 1; shadowGenerator.blurKernel = 60; //接收陰影
plane.receiveShadows=true; //陰影計算默認1秒60次,靜態陰影改成1次就能夠了;
shadowGenerator.getShadowMap().refreshRate =BABYLON.RenderTargetTexture.REFRESHRATE_RENDER_ONCE //(0)We need to compute it just once //讓燈不要從新計算陰影位置
light.autoUpdateExtends = false; //取消泊松亮斑
shadowGenerator.bias=0.001; //webGL2.0
usePercentageCloserFiltering=true;


## 世界座標系 與 本地座標系
1. lookAt(vector)是以z軸指向vector這個點的位置,使用這個值後,會清零rotation,並將本地軸的信息存放在rotationQuaternion中。
2. 本地軸默認爲世界座標系(左手座標系).
3. 若要使用本地座標系,可使用

* position * rotation * translate(vector,distance,BABYLON.Space.LOCAL) * rotate(vector,distance,BABYLON.Space.LOCAL)

4. 若是須要使用世界座標系

* rotate(vector,distance,BABYLON.Space.WORLD) * translate(vector,distance,BABYLON.Space.WORLD)

5. 位移(position,translate)都是沿着世界座標系或者父元素的本地座標系進行位移,若要沿着本身的本地軸進行位移,則

* locallyTranslate(vector)

6. 若是設置了rotationQuaternion,那麼本地軸存放在rotationQuaternion中(若是3DSMAX中導出軸不是世界座標系,那麼本地軸也存放在這裏,不然的話這個值爲undefined

## 優化
1. material.freeze();

scene.freezeMaterials();

凍結後,即便更改材質的屬性,着色器也將保持不變。您將不得不解凍它來更新內部着色器:

material.unfreeze();
scene.unfreezeMaterials();

2. 默認狀況下,Babylon.js使用索引的網格,其中頂點能夠由面部重用。當頂點重用率低時,若是頂點結構至關簡單(就像一個位置和一個正常的),那麼你可能須要展開頂點並中止使用索引

mesh.convertToUnIndexedMesh();

例如,這對於立方體來講很是有效,其中更有效地發送32個位置而不是24個位置和32個索引。


3. 默認狀況下,Babylon.js將適應設備比例,以便在高DPI設備上產生最佳質量。
缺點是這可能會在低端設備上花費不少。您可使用Engine構造函數的第四個參數關閉它:

var engine = new BABYLON.Engine(canvas, antialiasing, null, false);

咱們也能夠經過設置精度來下降FPS消耗

engine.setHardwareScalingLevel(1~10)

4. BABYLON.SceneOptimizer.OptimizeAsync(scene);
等同於:

BABYLON.SceneOptimizer.OptimizeAsync(scene, BABYLON.SceneOptimizerOptions.ModerateDegradationAllowed(), function() { // On success
}, function() { // FPS target not reached
})

5. 當mesh的頂點數量太多,檢測碰撞時候最好開啓子網格,子網格進行檢測

mesh.subdivide(x) mesh.createOrUpdateSubmeshesOctree(capacity, maxDepth) mesh.useOctreeForCollisions mesh.useOctreeForPicking mesh.useOctreeForRenderingSelection //var octree=scene.createOrUpdateSelectionOctree(); //for(var i=0;i<scene.meshes.length;i++){ // octree.dynamicContent.push(scene.meshes[i]) //}

6.createInstance();

synchronizeInstances()

實例對象的LOD繼承sourceMesh的LOD


7.LOD
LOD的對象無論原來的位置,旋轉是什麼,都以sourceMesh的位置,旋轉爲準。

addLODLevel();

8.簡化網格,生成不一樣faces的LOD

simplify(settings, parallelProcessing, simplificationType, successCallback) → void
//scene.meshes[0].simplify([{ quality: 0.1, distance: 10000 }], // true, BABYLON.SimplificationType.QUADRATIC, function() { // alert("LOD finisehd, let's have a beer!"); // });

## 廣告板

plane.billboardMode = BABYLON.Mesh.BILLBOARDMODE_Y;

## 判斷是否爲手機

var os = function() { var ua = navigator.userAgent, isWindowsPhone = /(?:Windows Phone)/.test(ua), isSymbian = /(?:SymbianOS)/.test(ua) || isWindowsPhone, isAndroid = /(?:Android)/.test(ua), isFireFox = /(?:Firefox)/.test(ua), isChrome = /(?:Chrome|CriOS)/.test(ua), isTablet = /(?:iPad|PlayBook)/.test(ua) || (isAndroid && !/(?:Mobile)/.test(ua)) || (isFireFox && /(?:Tablet)/.test(ua)), isPhone = /(?:iPhone)/.test(ua) && !isTablet, isPc = !isPhone && !isAndroid && !isSymbian; return { isTablet: isTablet, isPhone: isPhone, isAndroid : isAndroid, isPc : isPc }; }();

## actionManager

1.mesh.actionManager = new BABYLON.ActionManager(scene); 2.mesh.actionManager.registerAction(new BABYLON.InterpolateValueAction(BABYLON.ActionManager.OnPickTrigger, light, "diffuse", BABYLON.Color3.Black(), 1000)); 3.mesh.actionManager.registerAction(new BABYLON.ExecuteCodeAction(BABYLON.ActionManager.OnPointerOverTrigger, function(){ })) actionmanager{ additionalData: source: pointerX: pointerY: sourceEvent: }

## onPointerObservable

scene.onPointerObservable.add(function(e){ e.type:1,  //1.onmousedown //2:onmouseup //4:onmousemove
 e.event:sourceevent, e.pickInfo:{ hit: pickedMesh: pickedPoint:vec3 } })

## 輝光

//mainTextureRatio略微調大點,解決輝光閃爍
var hl = new BABYLON.HighlightLayer("dianchiMat", scene, {mainTextureRatio: 1.5});

### toDataURL

//先進行設置
var engine = new BABYLON.Engine(canvas, antialiasing, { preserveDrawingBuffer: true, }, false); canvas.toDateURL();

## GUI

var gui = BABYLON.GUI.AdvancedDynamicTexture.CreateForMesh(plane, 1024, 1024, false); var control = new BABYLON.GUI.Image(plane.name + "_gui", "img/function/" + (index + 1) + ".png"); gui.addControl(control) control.width usableWidth = width - paddingLeft - paddingRight control.left control.top

## 獲取模型的在畫布上面的二維座標

var mesh2d = BABYLON.Vector3.Project(mesh.position, BABYLON.Matrix.Identity(), scene.getTransformMatrix(), camera.viewport.toGlobal(engine.getRenderWidth(), engine.getRenderHeight())); console.log(mesh2d.y) console.log(mesh2d.x)

在最小寬度爲760因此小於760的尺寸如移動端 必須使用百分比獲取座標

var mesh2d = BABYLON.Vector3.Project(mesh.position, BABYLON.Matrix.Identity(), scene.getTransformMatrix(), camera.viewport.toGlobal(engine.getRenderWidth(), engine.getRenderHeight())); console.log(mesh2d.y/engine.getRenderHeight()*100+"%")
console.log(mesh2d.x/engine.getRenderWidth()*100+"%")
var options = new BABYLON.SceneOptimizerOptions(50, 2000); options.addOptimization(new BABYLON.HardwareScalingOptimization(0, 1));
相關文章
相關標籤/搜索