前言:公司用BABYLON作為主要的前端引擎,同事們在長時間的項目實踐中摸索到有關BABYLON的學習路徑和問題解決方法,這里只作為溫故知新。
一、快速學習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/)
二、需要掌握的基本技能 |
1. engine,scene等創建,抗鋸齒,像素比,深度緩沖區等配置項
2. 燈光的創建,基本屬性,作用域
3. 相機的創建,基本屬性,多相機的切換,綁定等
4. 材質的創建,不同紋理類型等
5. 場景中的元素,霧化,天空盒,陰影,地形圖,世界坐標系,本地坐標系等
6. 事件,actionManager,onPointerDownObservable,pick,pickWithRay,
onViewMatrixChangedObservable,onLightRemovedObservable等基本事件
7. UI
三、項目開發中遇到的一些問題及重點功能 |
# 燈光
//設置作用物體
light.includedOnlyMeshes //設置排除物體
light.excludedMeshes
# 相機
1、相機多個動畫的正確順序
targetScreenOffet->target->beta->alpha->radius
2、相機運動觸發的事件
camera.onViewMatrixChangedObservable
3、漫游相機定制跳躍轉向碰撞等功能
//有兩種方法可以根據世界矢量進行碰撞位移
//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);
# 材質
1、材質特殊參數
material.maxSimultaneousLights //最多可接受燈光個數,默認4個 material.useLogarithmicDepth material.needDepthPrePass //深度判斷 material.transparencyMode=2;
2、 dynamicTexture
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;
3、鏡面反射材質
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
4、 探針
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;
5、 菲涅爾
//所有菲涅爾類型
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. 綁定鍵值對
animation.setKeys([{frame:0,value:0},...])
3. 設置運動函數
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,..]
3、members particleSystem.disposeOnStop=true;
# mesh
1、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
2、 獲取軸心
//如果之前有freeze矩陣,則需要先重新計算
mesh.computeWorldMatrix(true) mesh.getAbsolutePivotPoint()
3、設置本身軸偏差
mesh.setPivotPoint(vec3)
4、畫線
var lines=new BABYLON.Mesh.CreateLines("line",[v0,v1,v2,v3],scene) //畫線默認是以gl.LINES方法繪畫,例子中雖然只傳入了4個頂點,但是默認0,1 1,2 2,3 //顏色:lines.color
5、自定義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)
6、使用自定義的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);
7、一般用到的創建着色器程序的兩種方法

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);
//方法一. 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默認傳入的參數
1、自動傳入的uniform變量
world,
view,
projection,
worldView,
worldViewProjection
cameraPosition
2、自動傳入的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來增加頂點
# 場景
1、自己創建天空盒
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;
2、利用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);
3、利用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));
版權聲明:本文整理只做學習,未經允許不得轉載