记录babylonjs使用过程中遇到的一些问题

  • 设置颜色时颜色出现偏差
    https://forum.babylonjs.com/t/wrong-albedo-colors/17993
    原因: PBR材质的颜色空间为线性,而当我们通过浏览器的拾色器等去选取颜色的时候,这是的空间是gamma 空间(即颜色时经过gamma矫正过的)。(可以理解为在两个不同的坐标系之后,所以会存在偏差);
    解决办法:new Color3(11 / 255, 102 / 255, 71 / 255).toLinearSpace()

  • 设置贴图时贴图翻转了(可能和导出时的设置有关)
    解决办法:new Texture('textureName', scene, true, false);
    把第四个参数设置为false

  • 纹理压缩
    .basis文件: basis_universal 纹理压缩(https://github.com/BinomialLLC/basis_universal)
    .dss文件: DirectDraw Surface的缩写,它是DirectX纹理压缩(DirectX Texture Compression,简称DXTC)的产物。

  • 模型导出后材质没有效果

    • 在blender的材质系统中,只能使用原理性 BSDF(双向散射分布函数)的材质类型(和前端的PBR材质相对应)
    • 对于一些程序化材质(由程序生成的纹理),前端也是不能显示的,需要把纹理烘焙成贴图的形式
  • 模型渲染效果差

    • 首先确保渲染引擎没有刻意去降低渲染质量(初始化时一般默认的效果就不错了)
    • 给场景添加合适的hdr环境贴图
    • 必要时可以加上灯光
    • 对模型渲染要求较高时,需要设计师在建模软件里面把一些常用的贴图给烘焙出来(清漆、反射、金属度、金属粗糙度、发光、凹凸、法相贴图等等)
  • 自定义shader时在gl_FragColor输出带透明度的颜色时gl_FragColor.a = 0.5透明度不生效

    • 解决办法:
      • new ShaderMaterial时设置needAlphaBlending: true, needAlphaTesting: true
      • 设置当前材质的alpha不为1 shaderMaterial.alpha = 0.99
  • gltf/glb文件带音频

    • 依赖于MSFT_audio_emitter 的扩展
    • https://github.com/KhronosGroup/glTF/issues/1582
    • https://github.com/KhronosGroup/glTF/blob/8109e86a26c9210814f8d236589ce92a2f9fa8f8/extensions/2.0/Vendor/MSFT_audio_emitter/README.md#clip
    • https://github.com/KhronosGroup/glTF/issues/1582
  • 世界坐标系和本地坐标系转换

    • 世界坐标到本地坐标
      • const positionWorld = new Vector(1,2,1)
      • const matrix = mesh.getWorldMatrix().clone().invert();(注意需要克隆一份,否则会造成奇怪的现象(说多了都是泪。。。。))
      • const positionLocal = Vector3.TransformCoordinates(positionWorld, matrix);
    • 本地坐标到世界坐标
      • const positionLocal = new Vector(0,0,1)
      • const matrix = mesh.getWorldMatrix().clone();(这里不要invert)
      • const positionWorld = Vector3.TransformCoordinates(positionLocal, matrix);
    • 上面提到的Vector3.TransformCoordinates,类似于threejs中的Vector3.applyMatrix4
  • 让一个二维平面永远朝向相机

    • axis1 = (position1).subtract(position2);
    • axis3 = BABYLON.Vector3.Cross(camera.position, axis1);
    • axis2 = BABYLON.Vector3.Cross(axis3, axis1);
    • mesh.rotation = BABYLON.Vector3.RotationFromAxis(axis1, axis2, axis3);
  • 模型导入后内外颠倒

    • 由于模型建模时使用的工具坐标系和babylon引擎的坐标不一致导致,通常引擎会自动设置scale(1,1,-1)来抵消这种差异
  • 绕任意轴旋转mesh

/**
 *
 * @param mesh
 * @param axis Vector3 旋转轴
 * @param angle number 旋转角度
 * @param offset Vector3 偏移值
 */
function createRotateWithAxis(scene: Scene, mesh: AbstractMesh, axis: Vector3, offset = new Vector3(0, 0, 0)): (a: number) => void {
  const center = offset.scale(-1); // 旋转中心
  // 辅助线 查看旋转轴
  MeshBuilder.CreateLines("axisLine", { points: [center.add(axis.scale(-50)), center.add(axis.scale(50))] }, scene);

  const pivot = new TransformNode("root");
  pivot.position = center;
  mesh.parent = pivot;
  mesh.position = offset;

  // 1.设置pivot的朝向和位置
  const transformNode = new TransformNode("transformNode", scene);
  transformNode.position = mesh.position.clone();
  transformNode.lookAt(transformNode.position.add(axis));

  // 2.校正旋转轴 (有时mesh旋转轴不是mesh的forward的方向,这是可以用下面这个方法来对齐)
  // 围绕x轴旋转transformNode90度,以与网格的默认方向对齐
  // transformNode.rotate(Axis.X, Math.PI/2, Space.LOCAL);

  // 3.饮用pivot的rotationQuaternion到目标mesh上
  transformNode.rotationQuaternion && mesh.rotation.copyFrom(transformNode.rotationQuaternion.toEulerAngles());

  function rotateFn(angle: number) {
    pivot.rotate(axis, angle, Space.LOCAL);
  }

  return rotateFn;
}
  • 截图时在玻璃材质中有上一帧的残影

    • 解决方法:连续的截两次,只用第二次的截图
  • ArcRotateCamera设置position不起作用

    • 解决方法:设置position的值之后,需要手动调camera.rebuildAnglesAndRadius()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值