为什么要用babylonJS

为什么要用babylonJS

webGL. threeJS. babylonJS对比

引用网上一位资深开发者的话:WebGL原生开发好比远古时期的投石索,既原始又难以控制,但通过不断使用投石索锻炼出来的强壮体魄可以在任何情况下给予你支持;Three.js好比AK47,简单粗暴又威力强大,在特定情况下能够快速解决问题,但当你想深入研究时又发觉难以控制;Babylon.js好比绝地武士的光剑,外形简约但变化无穷,一剑在手顿感原力与你同在(丰富的教程和社区)。

webGL:更加原生,对于前端开发者来说学习成本比较大,相当于一种新的语言,偏向于c语言,更加底层。
threeJS:是纯渲染引擎,而且代码易读,容易作为学习WebGL、3D图形、3D数学应用的平台,也可以做中小型的重表现的Web项目。API很多,但是文档相对太少,不稳定因素太大,适合做小型demo。
babylonJS:一款游戏开发引擎,有比较完善的开发团队(微软),文档完善且更新及时,支持TS,相对稳定,优化方面相对比较好,适合做大型项目,交互事件完善。

为什么要用babylonJS

在这里插入图片描述

babylonJS相关API简介

创建数学计算形状的简单方法是这样的:

  • 选择2D数学曲线
  • 得到它的参数方程
  • 使用一个简单的for循环计算Vector3来填充一个数组迭代所需的点数(在2D平面中设置它们以开始,例如z = 0
  • 使用BABYLON.Mesh.CreateLines(“name”,yourArray,scene)检查曲线
  • 通过改变x或y推导出你的第一条曲线并在z上迭代,因为将每个派生路径添加到路径数组中
  • 在每次z迭代时再次检查BABYLON.Mesh.CreateLines(“name”,yourArray,scene)
  • 最后使用paths数组构建功能区

创建形状的主要规则应该是:

  1. 如果只是基本形状,使用BJS的基本形状
  2. 如果需要许多基本形状组成的形状,使用构造基础几何体或MergeMeshes方法
  3. 如果需要具有对称轴的几何形状,使用CreateTube或extrusion
  4. 如果需要别的,可以使用CreateRibbon和一些数学知识实现

BABYLON渲染顺序

  1. 设置了depth属性的meshes
  2. 不透明的meshes
  3. 具有alpha属性的meshes
    对于使用StandardMaterial的网格,如果它的材料.hasAlpha设置为true
    如果是其他类型的材料,如果材料的.needAlphaTesting()返回true
  4. alpha混合meshes,按depth排序(等于到相机的距离)
    任何网格都有
    1. 属性hasVertexAlpha设置为true(如果顶点具有单独的alpha(透明度)值,则自动为导出的网格设置)
    2.visibility值<1
    对于使用StandardMaterial的网格,如果它具有:
    1.定义了不透明度纹理
    2.不透明菲涅耳效应活跃
    其他类型的材料
    1.needAlphaBlending()功能返回true
  5. sprites
  6. particles

渲染组
可渲染的对象可以组织到渲染组中,每个渲染组将使用上面的顺序
如何使用:在图层对象上设置.renderingGroupId = 1 (默认ID为0)
渲染组按ID升序呈现,从0开始,渲染组有效值0,1,2,3共四组
此属性可用于meshes,sprites, particles

Alpha
通过.alphaIndex = Number.MAX_VALUE(默认值)设置,最高值为(1.79E+308)
alpha-blended 首先按alpha索引排序,然后按depth排序
此属性仅适用于Alpha混合网格

BJS场景内容

  • 场景
 let canvas = document.getElementById("renderCanvas");
 let engine = new BABYLON.Engine(canvas, true);
 let scene = new BABYLON.Scene(engine);
  • 相机
    camera.resetToCurrentRotation():重置旋转轴为Y轴

相机种类

  1. UniversalCamera(通用相机,支持键盘,鼠标,触摸,游戏手柄
  2. ArcRotateCamera(弧形相机,目前项目中常用的相机)
  3. FollowCamera(跟随相机,参数:radius与目标的距离;heightOffset目标上方的高度;rotationOffset旋转偏移值;cameraAcceleration相机移动到目标位置其加速度;maxCameraSpeed最大可达到的速度)
  4. AnaglyphCameras(3D相机)
  5. DeviceOrientationCamera(用于移动端,可根据陀螺仪作出相应的倾斜)
  6. VRDeviceOrientationFreeCamera(VR设备相机)
  7. WebVRFreeCamera(webVR相机)
  8. FlyCamera(飞行相机)

使用相机模拟碰撞检测及重力影响

  1. scene.gravity = new BABYLON.Vector3(0, -9.81, 0) //设置重力矢量
  2. camera.applyGravity = true; //将重力应用于相机
  3. camera.ellipsoid = new BABYLON.Vector3(1,1,1);//相机的默认尺寸为(0.5,1,0.5)的椭圆体:相机的椭圆体是有偏移量的,可通过camera.ellipsoidOffset来设置
  4. scene.collisionsEnabled= true;
    camera.checkCollisions = true;//开启碰撞检测
  5. ground.checkCollisions = true;
    box.checkCollisions = true;//声明需要开启碰撞检测的物体
  • 灯光
    light.setEnabled(true)// 开启灯光
    light.intensity = 1// 灯光强弱
    light.range = 100// 用于点光源和聚光灯,光线到达的距离
    light.diffuse = new BABYLON.Color3(1, 0, 0);// 灯光颜色
    light.specular = new BABYLON.Color3(0, 1, 0); //照射到物体反射的颜色
    light.groundColor = new BABYLON.Color3(0, 1, 0); //物体背面的颜色,用于半球光
    light.excludedMeshes.push(box1)// 将物体box1排除在light之外

种类

  1. let light = new BABYLON.PointLight(“pointLight”, new BABYLON.Vector3(1, 10, 1), scene); //点光源
  2. let light = new BABYLON.DirectionalLight(“DirectionalLight”, new BABYLON.Vector3(0, -1, 0), scene);// 定向光
  3. let light = new BABYLON.SpotLight(“spotLight”, new BABYLON.Vector3(0, 30, -10), new BABYLON.Vector3(0, -1, 0), Math.PI / 3, 2, scene);// 聚光灯:位置,方向,角度,指数
  4. let light = new BABYLON.HemisphericLight(“HemiLight”, new BABYLON.Vector3(0, 1, 0), scene);// 半球光
  • 阴影webGL相关描述
    scene.shadowEnabled = true
    let shadowGenerator = new BABYLON.ShadowGenerator(1024, light)
    shadowGenerator.getShadowMap().renderList.push(mesh)
    ground.receiveShadows = true
    shadowGenerator.setDarkness(0-1)设置阴影明暗程度
    addShadowCaster(mesh, includeDescendants):辅助函数,用于将mesh及其后代添加到阴影轮廓中
    removeShadowCaster(mesh, includeDescendants):删除轮廓

分类

  1. shadowGenerator.usePoissonSampling = true (泊松采样,柔化阴影,效果好,渲染速度慢)
  2. shadowGenerator.useExponentialShadowMap = true(指数阴影贴图)
  3. shadowGenerator.useBlurExponentialShadowMap = true
    (模糊指数阴影贴图:
    shadowGenerator.blurScale缩小阴影贴图比例,默认值2,
    shadowGenerator.blurBoxOffset模糊框边缘偏移量,默认值1,
    shadowGenerator.useKernelBlur使用内核模糊而非框模糊,效果好,但是耗费性能,此时可用shadowGenerator.blurKernel来控制大小,默认值为1
    )
  4. shadowGenerator.useCloseExponentialShadowMap = true(近似指数阴影贴图,3.0版本启用,可获取准确的自阴影,需要设置light.shadowMinZ及light.shadowMaxZ,范围越小效果越好,且保证灯光尽可能的靠近物体)
  5. shadowGenerator.useBlurCloseExponentialShadowMap = true(模糊近似指数阴影贴图)
  6. shadowGenerator.usePercentageCloserFiltering = true (近似百分比过滤阴影贴图,BJS3.2启用,调用webGL2的新硬件过滤功能,极大改善阴影的性能和设置,但是小平台可用资源较少,目前仅支持Point和Directional光源,可用shadowGenerator.filteringQuality = BABYLON.ShadowGenerator.QUALITY_LOW调节质量与性能之间的最佳权衡)
  7. shadowGenerator.useContactHardeningShadow = true(接触硬化阴影,为PCF升级版,处理器性能要求更高,应用于桌面应用程序,当阴影远离物体时,会变得更柔和,目前仅支持Point和Directional光源,需要定义light.shadowMinZ和light.shadowMaxZ,范围越小,阴影越好,使用shadowGenerator.contactHardeningLightSizeUVRatio更改阴影弱化速度,范围0-1,可使用shadowGenerator.filteringQuality = BABYLON.ShadowGenerator.QUALITY_LOW权衡性能)

灯光:

可产生阴影的灯光有

  1. Point lights(点光源,使用cubemaps,因此使用时可能会产生性能问题,不支持BlurExponentialShadowMap和CloseBlurExponentialShadowMap )
  2. Spot lights(聚光灯,使用透视投影计算阴影贴图)
  3. Directional lights(定向灯,使用正交投影,既初始化时阴影已经确定,不能在更改,
    light位置会自动评估,可通过light.autoUpdateExtends = false关闭;
    light.shadowOrthoScale默认值为0.1,表示投影窗口从最佳大小增加10%;
    light.shadowFrustumSize,默认off,值为0,)

几点优化

  1. shadowGenerator.bias = 0.00005(偏压,增加遮挡物深度以促进自阴影,优化阴影痤疮)
  2. shadowGenerator.forceBackFacesOnly = true (增加背面阴影渲染)
  3. 设置light.shadowMinZ和light.shadowMaxZ,通过减少minZ和maxZ之间的距离来获得更精确的阴影贴图
  4. 使用useCloseExponentialShadowMap
  5. 使用shadowGenerator.frustumEdgeFalloff = 0-1;边缘衰减
  6. 如果是一个静态的世界
    1⃣️冻结阴影发生器shadowGenerator.getShadowMap().refreshRate = BABYLON.RenderTargetTexture.REFRESHRATE_RENDER_ONCE;
    2⃣️要求灯光不重新计算阴影位置light.autoUpdateExtends = false;
  7. 当加载的外部模型有问题的时候,在加载场景之前使用BABYLON.SceneLoader.CleanBoneMatrixWeights = true自动清理权重

例子:
let shadowGenerator = new BABYLON.ShadowGenerator(1024, light);//定义一个阴影材质
shadowGenerator.bias = 0.001; // 设置阴影偏差以取消自阴影痤疮
shadowGenerator.normalBias = 0.02;// BJS3.2参数,用来修复阴影偏差值
light.shadowMaxZ = 100;
light.shadowMinZ = 10; //使用阴影偏差而产生的peter panning,通过更改贴图大小范围来修复
shadowGenerator.useContactHardeningShadow = true; //使用接触硬化阴影
shadowGenerator.contactHardeningLightSizeUVRatio = 0.05; //阴影衰减值
shadowGenerator.setDarkness(0.5); //阴影模糊值

BJS基本形状

  • 盒子:let box = BABYLON.MeshBuilder.CreateBox(“myBox”, {height: 5, width: 2, depth: 0.5}, scene)
  • 球体:let sphere = BABYLON.MeshBuilder.CreateSphere(“mySphere”, {diameter: 2, diameterX: 3}, scene);
  • 平面:let myPlane = BABYLON.MeshBuilder.CreatePlane(“myPlane”, {width: 5, height: 2}, scene);
  • 地面:let myGround = BABYLON.MeshBuilder.CreateGround(“myGround”, {width: 6, height: 4, subdivsions: 4}, scene);
  • 精灵: let spriteManagers = new BABYLON.SpriteManager(“Manager”, “xxx.png”, 200,
    800 OR {width:64, height:64}, scene)(名称,2D图像,此管理器中最大实例数,图像大小,要加入的场景)
    let player = new BABYLON.Sprite(“player”, spriteManagers)
    作用:实现动画效果 player.playAnimation(0, 40, true, 100)
    player.cellIndex = 30; 去指定图像
  • 粒子:let particleSystem = new BABYLON.ParticleSystem(“particles”, 2000,
    scene); particleSystem.particleTexture = new
    BABYLON.Texture(“xx.png”,scene);

BJS相关事件

  1. 通过鼠标获取模型信息
  2. RayCasts:光线投射,通过此功能可获取模型信息或碰撞检测;
  3. scene.onPointerDown = function(event, pickResult){} 鼠标点下获取模型信息
  4. box.backFaceCulling = false; //背面剔除 box1.intersectsMesh(box2,
    false):第二个参数为边界框精度,true时精度较高但计算成本高 box1.intersectsPoint(new
  5. BABYLON.Vector3(10,10,10)) //检测是否接触某一点
  6. scene.registerBeforeRender(function(){ }) //持续渲染动画
  7. box.position.copyFrom(box2.position)//复制属性
  8. 设置mesh层级mesh.renderingGroupId=1
  9. pickInfo.getNormal(true) 可通过点击获取模型信息

相关问题汇总

  1. 把mainTextureRatio略微调大点可以解决辉光闪烁的问题
    new BABYLON.HighlightLayer(“dianchi”, scene,{mainTextureRatio:1.5});
  2. 第一人称相机或物体开启重力在不移动的情况下会停止掉落,可通过camera._needMoveForGravity = true 开启
  3. 视频材质的一些属性不能直接设置,需要视频加载完成后才可以,设置如下。
    var videoTexture = new BABYLON.VideoTexture(“video”, [“video.mp4”,“textures”], scene, false, false);
    videoTexture.video.loop=true; //无效
    scene.registerBeforeRender(function(){
    if(videoTexture.isReady()==true){
    videoTexture.video.loop=true //有效
    }
    })
  4. 移动端锯齿严重问题可通过 engine.setHardwareScalingLevel(0.4)
  5. 动态阴影不精确可以调下面的参数设置灯光阴影的范围
    light = new BABYLON.DirectionalLight(“Dir0”, new BABYLON.Vector3(10, -3, -10), scene); light.intensity = 2;
    light.position=new BABYLON.Vector3(-26, 4, 43);
    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;
    })
  • 12
    点赞
  • 48
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值