U3DC.COM | 优三帝研究院

Menu

关于Unity导出场景用于Three.js的研究

前言
主要流程构思:
  1. 在 Unity 中创建场景
  2. 使用 FBX Exporter 导出 FBX
  3. 使用 FBX2glTF 将 FBX 转换为 glTF
  4. 使用 Three.js 加载 glTF
你可以在 Three.js 中直接使用从 Unity 导出的 FBX,但是 glTF 比 FBX 更容易处理,所以这里我将它转换为 glTF。
本文使用的Unity和three.js的版本分别是:
在 Unity 中创建场景
首先,在 Unity 中创建要导出的场景。这次我们将放置多个网格和相机、动画相机,将导出目标合并为一个游戏对象 ( Root)。

添加图片注释,不超过 140 字(可选)
相机动画看起来像这样:

添加图片注释,不超过 140 字(可选)
 
使用 FBX Exporter 导出 FBX
在 Unity 中安装 FBX 导出器。FBX 导出器驻留在包管理器的 Unity 注册表中。

About FBX Exporter​docs.unity3d.com

安装 FBX Exporter 后,选择要导出的游戏对象Menu > GameObject > Export to FBX...并单击(或右键单击游戏对象并Export to FBX...)单击Export Options显示,设置如下,并按下Export按钮将FBX导出到指定路径。

添加图片注释,不超过 140 字(可选)
 
使用 FBX2glTF 将 FBX 转换为 glTF
使用 FBX2glTF 将从 Unity 导出的 FBX 转换为 glTF。

https://github.com​github.com

 

添加图片注释,不超过 140 字(可选)
你可以自己build构建一个版本,或者可以直接从发布页面获取每个操作系统的预构建可执行文件,我们直接下载一个版本是最方便的。
在Mac平台,使用终端命令来转换为 glTF,如下所示。FBX2glTF 有很多选项,例如 droco 压缩,但这次我将简单地将其转换为二进制格式(GLB)。执行时会在同一目录下生成UnityToThreejs.glb
$ chmod +x ./FBX2glTF-darwin-x64 $ ./FBX2glTF-darwin-x64 --binary ./UnityToThreejs.fbx
使用 Three.js 加载 glTF
使用 Three.js 加载创建的 glTF。使用 GLTFLoader 进行加载。
<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Unity to Three.js</title>
    <style>
      body {
        margin: 0;
        overflow: hidden;
      }
    </style>
  </head>
  <body>
    //使用three.js库
    <script src="./lib/threejs/three.min.js"></script>
    <script src="./lib/threejs/examples/loaders/GLTFLoader.js"></script>
    <script>
      const renderer = new THREE.WebGLRenderer();
      renderer.setSize(window.innerWidth, window.innerHeight);
      renderer.setPixelRatio(window.devicePixelRatio);
      document.body.appendChild(renderer.domElement);

      const scene = new THREE.Scene();
      scene.background = new THREE.Color(0x999999);

      const dirLight = new THREE.DirectionalLight(0xffffff, 1.0);
      dirLight.position.set(-1.0, 3.0, -1.0);
      scene.add(dirLight);
      const ambLight = new THREE.AmbientLight(0x333333);
      scene.add(ambLight);

      let camera = null;
      let mixer = null;

      const loader = new THREE.GLTFLoader();
      loader.load('./assets/UnityToThreejs.glb', (gltf) => {
        // 播放动画
        mixer = new THREE.AnimationMixer(gltf.scene);
        gltf.animations.forEach((animation) => {
          mixer.clipAction(animation).play();
        });

        const gltfCamera = gltf.cameras[0];
        camera = new THREE.PerspectiveCamera(
          gltfCamera.fov,
          window.innerWidth / window.innerHeight,
          // 相机的near和far转换成FBX时以厘米为单位
          // 在FBX2glTF中不转换成米,所以在此转换成米单位
          gltfCamera.near * 0.01,
          gltfCamera.far * 0.01
        );
        // 为了应对照相机动画中存在的迷之旋转
        // 利用抵消的旋转追加到glTF相机的子要素中
        camera.rotation.set(0, -0.5 * Math.PI, 0);
        gltfCamera.add(camera);

        scene.add(gltf.scene);
      });


      function resize() {
        renderer.setPixelRatio(window.devicePixelRatio);
        renderer.setSize(window.innerWidth, window.innerHeight);
        camera.aspect = window.innerWidth / window.innerHeight;
        camera.updateProjectionMatrix();
      }
      window.addEventListener('resize', resize);

      const clock = new THREE.Clock();

      function animate() {
        requestAnimationFrame(animate);

        // 动画更新
        if (mixer) {
          mixer.update(clock.getDelta());
        }

        if (camera) {
          renderer.render(scene, camera);
        }
      }
      animate();
    </script>
  </body>
</html>

 

由于某种原因,相机动画相对于 Y 轴旋转了 90 度,所以不要直接使用 glTF 加载的相机,而是rotation添加一个相机集来偏移子元素的旋转并使用该相机进行绘制。我正在这样做. (相机在 Y 轴上旋转 90 度的问题也发生在加载 FBX 时,无论是否有 FBX 动画。不适用于没有动画的 glTF。可能是 FBX2glTF 我想我会在没有动画时修复旋转,但不是动画的旋转。)
Three.js的绘制如下。现在可以导出 Unity 场景并在 Three.js 中渲染出来。

添加图片注释,不超过 140 字(可选)
 
两种方案比较
顶部是 Unity导出方案,底部是纯Three.js 实现的方案。由于照明和材质的不同,无法渲染出完全相同的效果,但这里尽可能以相同的方式安排模型和相机运动。

添加图片注释,不超过 140 字(可选)
 

添加图片注释,不超过 140 字(可选)
文献参考
打赏
— 于 共写了3101个字
— 文内使用到的标签:

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据