【原创】Babylon.js的一些笔记。

转载该文章请发邮件到:hi@renjianfeng.com说明情况,删除该段文字视为侵权!
babylonjs笔记
Babylonjs/threejs技术群(QQ群):154398355

一、天空盒子
1.天空盒子的6面贴图对应如下

right -> px
top -> py
front -> pz
left -> nx
bottom -> ny
back -> nz

二、阴影
1.光源距离物体越近,阴影越精确。
2.点光源的阴影会出现 【泊松亮斑】

三、2D
1.获取模型的在画布上面的二维坐标

 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)

2.在最小宽度为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+"%")

四、材质
1.让我们模式的贴图支持【透明】展示

   //贴图
    Material.diffuseTexture=new BABYLON.Texture("images/dianguang.png", scene);
   //透明贴图
    Material.opacityTexture=new BABYLON.Texture("images/dianguang.png", scene);
    Material.opacityTexture.hasAlpha=true
    Material.diffuseTexture.hasAlpha=true

2.灯光

//模型禁用灯光
 Material.disableLighting=true

3.各种颜色

//自发光
Material.emissiveColor = new BABYLON.Color4(1, 1, 1,0)
//模型颜色
Material.diffuseColor= new BABYLON.Color4(1, 1, 1,0)
//模型高光颜色
Material.specularColor= new BABYLON.Color4(1, 1, 1,0)

4.各种强度

//材质高光强度
material.specularPower = value;
//灯光光强
light.intensity = value
//材质透明度
material.alpha= value

5.探针反射


//root:反射面(模型)
//others:反射源(模型数组)
//bias:反射程度

 function generateSatelliteMaterial(root, others,bias) {
            var probe = new BABYLON.ReflectionProbe("satelliteProbe" + root.name, 512, scene);
            for (var index = 0; index < others.length; index++) {
                probe.renderList.push(others[index]);
            }
            root.material.reflectionTexture = probe.cubeTexture;
            root.material.reflectionFresnelParameters = new BABYLON.FresnelParameters();
            root.material.reflectionFresnelParameters.bias = bias;
            root.material.reflectionFresnelParameters.leftColor=new BABYLON.Color4(150/255,150/255,150/255,0.5)
            root.material.reflectionFresnelParameters.rightColor=new BABYLON.Color4(61/255,61/255,61/255,0.5)
            probe.attachToMesh(root);
        }

6.伪反射天空盒

var reflectionTexture = new BABYLON.CubeTexture("images/skybox_tsl/cube", scene);
mesh.material.reflectionTexture=reflectionTexture

7.平镜面反射

material.reflectionTexture = new BABYLON.MirrorTexture("mirror", 512, scene, true);
//反射的位置深度参数
material.reflectionTexture.mirrorPlane = new BABYLON.Plane(0, -2, -0, 37);
//反射的模型列表
material.reflectionTexture.renderList = scene.meshes;
//反射程度
material.reflectionTexture.level = 0.08;

五、灯光
1.关闭/开启灯光

light.setEnabled(false/true);

2.灯光照射除指定模型以外的模型

light.excludedMeshes=[mesh1,mesh2...]

3.灯光照射除指定模型

light.includedOnlyMeshes=[mesh1,mesh2...]

4.bug
excludedMeshes和includedOnlyMeshes有可能在部分场景中失效,可采用下面的方式解决

 light.setEnabled(false);
 light.excludedMeshes=[mesh1,mesh2...]
 light.setEnabled(true);

5.颜色

//【灯光】漫射光颜色
 light.diffuse = new BABYLON.Color3()
//【灯光】镜面光颜色
 light.specular = new BABYLON.Color3()

六、位置
1.获取模型在画布上面的二维坐标

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

七、故障排除

1.贴图UV通道

Material.贴图类型.coordinatesIndex=number;

2.翻转贴图法线

mesh.flipFaces()

3.把mainTextureRatio略微调大点可以解决辉光闪烁的问题

new BABYLON.HighlightLayer("dianchi", scene,{mainTextureRatio:1.5});

4.第一人称相机或物体开启重力在不移动的情况下回停止掉落

camera._needMoveForGravity = true;

5.手动设置mesh层级

mesh.renderingGroupId=1

6.视频材质的一些属性不能直接设置,需要视频加载完成后才可以,设置如下。

 var videoTexture = new BABYLON.VideoTexture("video", ["video/video3.mp4","textures/babylonjs.webm"], scene, false, false);

 videoTexture.video.loop=true;  //无效

 scene.registerBeforeRender(function(){             
       if(videoTexture.isReady()==true){
             videoTexture.video.loop=true   //有效                              
       }                          
 })

7.移动端锯齿严重问题

engine.setHardwareScalingLevel(0.4)

9.动态阴影不精确可以调下面的参数设置灯光阴影的范围和平接头

light = new BABYLON.DirectionalLight("Dir0", new BABYLON.Vector3(10, -3, -10), scene);
        light.intensity = 2;
        light.position=new BABYLON.Vector3(-26.053449678125286, 4.620522808003314, 43.64921550154328)
        light.autoUpdateExtends=false;
        light.shadowFrustumSize=110

        shadowGenerator = new BABYLON.ShadowGenerator(4800, light);
        shadowGenerator.bias = 0.001;
        shadowGenerator.useBlurCloseExponentialShadowMap = true;
        // shadowGenerator.forceBackFacesOnly= true;
        shadowGenerator.depthScale=100
        //shadowGenerator.blurScale=0.6
        //  shadowGenerator.frustumEdgeFalloff = 10.0;
        light.shadowMinZ=0
        light.shadowMaxZ=100
        scene.meshes.forEach(function(mesh){
            shadowGenerator.getShadowMap().renderList.push(mesh);
            mesh.receiveShadows = true;
        })

10.骨骼动画导出错乱

3dsmax每个顶点支持的最多骨骼个数默认为20个,babylonjs最多支持每个顶点4个骨骼,你必须将3dsmax中的顶点最多支持的骨骼个数手动设置为4,这样就可以正常使用。
参考:http://doc.babylonjs.com/exporters/bones_influences_per_vertex

11.实时显示babylon二进制文件加载进度


var loadState=0;
        var loadState2=0;
        var _length=scene.getWaitingItemsCount();
        scene.registerBeforeRender(function(){
            if(loadState==0){
               console.log(parseInt((_length-scene.getWaitingItemsCount())/_length*100)+"%")
            }
            if(scene.getWaitingItemsCount()==0){
                loadState=1
                if(loadState2==0){
                    console.log("加载成功!")
                }
            }
        })

12.判断所有材质是否加载成功

 var materState=0;
        scene.registerBeforeRender(function(){
            if(materState==0){
                var _length=scene.textures.length;
                var _length2=0;
                scene.textures.forEach(function(texture){
                    if(texture.isReady() === true){
                        _length2++
                    }

                    console.log(parseInt(_length2/_length*100)+"%");
                })
                if(_length==_length2){
                    materState=1
                    console.log("材质加载成功!")
                    return false;
                }
            }
        })

13.alpha角度整除

 camera.alpha%(Math.PI*2)

番外篇
1.序列化场景

	var serializedScene = BABYLON.SceneSerializer.Serialize(scene);
	var strScene = JSON.stringify(serializedScene);
	
	// here is the serialized scene
	console.log(strScene);

2.将场景序列化为.babylon文件并下载

var objectUrl;
function doDownload(filename, scene) {
    if(objectUrl) {
        window.URL.revokeObjectURL(objectUrl);
    }
    
    var serializedScene = BABYLON.SceneSerializer.Serialize(scene);
        
    var strMesh = JSON.stringify(serializedScene);
    
    if (filename.toLowerCase().lastIndexOf(".babylon") !== filename.length - 8 || filename.length < 9){
        filename += ".babylon";
    }
            
	var blob = new Blob ( [ strMesh ], { type : "octet/stream" } );
       
    // turn blob into an object URL; saved as a member, so can be cleaned out later
    objectUrl = (window.webkitURL || window.URL).createObjectURL(blob);
    
    var link = window.document.createElement('a');
    link.href = objectUrl;
    link.download = filename;
    var click = document.createEvent("MouseEvents");
    click.initEvent("click", true, false);
    link.dispatchEvent(click);          
}

3.将探针反射保存为6个面并返回base64格式

scene.getMeshByName("Obj3d66-446277-3-868").material.environmentTexture.onAfterRenderObservable.add(function(){

                        var _size=scene.getMeshByName("Obj3d66-446277-3-868").material.environmentTexture._size

                        BABYLON.Tools.DumpFramebuffer(_size, _size, engine, function(i){
                            console.log(i)
                        }, "image/png", "ssss");
                    })

4.帧率锁步同步
js最高帧率刷新不稳定,且在不同的设备上面有不同的帧率,为了同步多端效果,可以通过下面的方式在每次刷新帧的时候先执行下面的代码同步时间差去累加矫正。

 var useTime;
if(lastSystemTime) {
    useTime = date.getTime() - lastSystemTime;
}else{
     useTime = 1000 / 30;
}
 //本次消耗的时间 / 正常每帧应该消耗的时间 算出倍率
var times = useTime / (1000/ 30);
//速度 * 倍率 = 本次应该移动的距离
 mesh.position.x -= Speed * times;

八、链接收藏

1.babylonjs编辑插件
https://github.com/ssatguru/BabylonJS-EditControl

2.如何使用固体颗粒系统
https://doc.babylonjs.com/overviews/solid_particle_system

3.vmf转obj
http://www.lagspike.com/converting-a-vmf-valve-map-file-to-udk/

九、免费模型下载推荐
http://artist-3d.com/free_3d_models/
http://www.aigei.com/3d/
https://sketchfab.com/
https://free3d.com/
http://www.xiadele.com/
http://www.cgmodel.com/
https://www.blendswap.com/

Top