记录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()
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Babylon.js 是一个基于 WebGL 技术的 3D 游戏引擎,能够在 Web 浏览器创建和渲染高品质的 3D 场景。以下是使用 Babylon.js 的基本步骤: 1. 引入 Babylon.js 库文件。您可以从 Babylon.js 的官方网站下载最新版本的库文件,将其引入您的 HTML 文件。 ```html <script src="https://cdn.babylonjs.com/babylon.js"></script> <script src="https://cdn.babylonjs.com/loaders/babylonjs.loaders.min.js"></script> ``` 2. 创建场景和相机。使用 `BABYLON.Scene` 类创建一个场景对象,并使用 `BABYLON.FreeCamera` 或 `BABYLON.ArcRotateCamera` 类创建一个相机对象。 ```javascript var canvas = document.getElementById("renderCanvas"); var engine = new BABYLON.Engine(canvas, true); var scene = new BABYLON.Scene(engine); var camera = new BABYLON.ArcRotateCamera("Camera", 0, 0, 10, BABYLON.Vector3.Zero(), scene); camera.attachControl(canvas, true); ``` 3. 加载模型。使用 `BABYLON.SceneLoader` 类从文件加载 3D 模型,并将其添加到场景。 ```javascript BABYLON.SceneLoader.ImportMesh("", "models/", "myModel.babylon", scene, function (newMeshes) { // 可以在此处对模型进行处理 // ... }); ``` 4. 创建光源。使用 `BABYLON.Light` 类创建一个光源对象,并将其添加到场景。 ```javascript var light = new BABYLON.PointLight("pointLight", new BABYLON.Vector3(0, 10, 0), scene); ``` 5. 渲染场景。使用 `BABYLON.Engine` 类的 `runRenderLoop` 方法渲染场景。 ```javascript engine.runRenderLoop(function () { scene.render(); }); ``` 这只是 Babylon.js 的一些基本用法,您可以参考官方文档了解更多功能和用法。Babylon.js 的官方文档地址为:https://doc.babylonjs.com/ 。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值