A郭恒 2022-08-04 11:44 采纳率: 83.3%
浏览 57
已结题

three.js +vue 渲染3d模型

问题遇到的现象和发生背景

刚接触 three.js

问题相关代码,请勿粘贴截图

主要就是 下载下来的3d模型 textures文件中 有多个图片 如何渲染上去

img

<script>
import * as THREE from "three";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js"; //引入动态模型的格式 可以选择FBX、OBJ或者COLLADA
export default {
  data() {
    return {};
  },
  methods: {
    //Three.js依赖一些要素,第一是scene,第二是render,第三是carmea。
    initThree() {
      const that = this;
      // 1.创建一个对象    scene   scene可以理解为我们将要渲染的环境、背景
      const scene = new THREE.Scene();
      // scene 换一个背景颜色
      scene.background = new THREE.Color("#eee");
      //  2.  获取dom 元素
      //3  创建一个WebGLRenderer,将canvas和配置参数传入:      不用自己写canvas 的话  会自动生成一个
      const canvas = document.querySelector("#three");
      const renderer = new THREE.WebGLRenderer({ canvas, antialias: true });
      //4 .  创建一个摄像机    比较常用的是PerspectiveCamera(透视摄像机)以及OrthographicCamera (正交投影摄像机)
      const camera = new THREE.PerspectiveCamera(
        50,
        window.innerWidth / window.innerHeight,
        0.1,
        1000
      );
      //生成的camera默认是放在中心点(0,0,0)的,但这是待会模型要放的位置,因此,我们把摄像机挪个位置:
      camera.position.z = 100;

      //  -1. 添加图片 单个纹理这样写
      // const gltfLoader = new GLTFLoader();
      // gltfLoader.load("/scenc1/scene.gltf", (gltf) => {
      //   const model = gltf.scene;
      //   //遍历模型每部分
      //   model.traverse((o) => {
      //     //将图片作为纹理加载    单个纹理这样写
      //     let explosionTexture = new THREE.TextureLoader().load(
      //       "/scenc1/textures/mask_metallicRoughness.png",
      //     );
      //     //调整纹理图的方向
      //     explosionTexture.flipY = false;
      //     //将纹理图生成基础网格材质(MeshBasicMaterial)
      //     const material = new THREE.MeshBasicMaterial({
      //       map: explosionTexture,
      //     });
      //     //给模型每部分上材质
      //     o.material = material;
      //   });
      //   scene.add(model);
      // });
      // -1-1   多个纹理tu
      const loader = new GLTFLoader();
      const textureLoader = new THREE.TextureLoader();
      loader.load("/scenc1/scene.gltf", function (gltf) {
        const model = gltf.scene;
        model.traverse((o) => {
          if (o.isMesh) {
            const materials = [
              new THREE.MeshBasicMaterial({
                map: textureLoader.load(
                  "scenc1/textures/coat_metallicRoughness.png"
                ),
              }),
              new THREE.MeshBasicMaterial({
                map: textureLoader.load(
                  "scenc1/textures/feather_baseColor.png"
                ),
              }),
              new THREE.MeshBasicMaterial({
                map: textureLoader.load(
                  "scenc1/textures/feather_metallicRoughness.png"
                ),
              }),
              new THREE.MeshBasicMaterial({
                map: textureLoader.load("scenc1/textures/feather_normal.png"),
              }),
              new THREE.MeshBasicMaterial({
                map: textureLoader.load(
                  "scenc1/textures/feather2_baseColor.png"
                ),
              }),
              new THREE.MeshBasicMaterial({
                map: textureLoader.load(
                  "scenc1/textures/feather2_metallicRoughness.png"
                ),
              }),
              new THREE.MeshBasicMaterial({
                map: textureLoader.load(
                  "scenc1/textures/Horn2_metallicRoughness.png"
                ),
              }),
              new THREE.MeshBasicMaterial({
                map: textureLoader.load("scenc1/textures/HornUp_baseColor.png"),
              }),
              new THREE.MeshBasicMaterial({
                map: textureLoader.load("scenc1/textures/mask_baseColor.png"),
              }),
              new THREE.MeshBasicMaterial({
                map: textureLoader.load(
                  "scenc1/textures/mask_metallicRoughness.png"
                ),
              }),
              new THREE.MeshBasicMaterial({
                map: textureLoader.load(
                  "scenc1/textures/material_emissive.png"
                ),
              }),
              new THREE.MeshBasicMaterial({
                map: textureLoader.load(
                  "scenc1/textures/material_metallicRoughness.png"
                ),
              }),
              new THREE.MeshBasicMaterial({
                map: textureLoader.load("scenc1/textures/material_normal.png"),
              }),
              new THREE.MeshBasicMaterial({
                map: textureLoader.load("scenc1/textures/staff_baseColor.png"),
              }),
              new THREE.MeshBasicMaterial({
                map: textureLoader.load(
                  "scenc1/textures/Staff_oval_baseColor.png"
                ),
              }),
            ];
            o.material = materials;
          }
        });
        scene.add(model);
      });

      //5 . 循环动画
      this.resizeRendererToDisplaySize(renderer);
      console.log(this.resizeRendererToDisplaySize(renderer));
      function animate() {
        // controls.update();
        renderer.render(scene, camera);
        requestAnimationFrame(animate); //循环的方法
        //添加下面代码
        if (that.resizeRendererToDisplaySize(renderer)) {
          const canvas = renderer.domElement;
          camera.aspect = canvas.clientWidth / canvas.clientHeight;
          camera.updateProjectionMatrix();
        }
      }
      animate();
    },
    // -2
    resizeRendererToDisplaySize(renderer) {
      const canvas = renderer.domElement;
      const width = window.innerWidth;
      const height = window.innerHeight;
      const canvasPixelWidth = canvas.width / window.devicePixelRatio;
      const canvasPixelHeight = canvas.height / window.devicePixelRatio;

      const needResize =
        canvasPixelWidth !== width || canvasPixelHeight !== height;
      if (needResize) {
        renderer.setSize(width, height, false);
      }
      return needResize;
    },
  },
  created() {},
  mounted() {
    this.initThree();
  },
};
</script>

运行结果及报错内容

没有报错 但是页面不显示
然后我改一下 materials 的格式就可以显示第一条
但是这只是一个颜色 如何将里面所有的图片全部渲染上去呢?

img

img

我的解答思路和尝试过的方法

我给他加个数组 但是就不显示了

我想要达到的结果

img

  • 写回答

1条回答 默认 最新

  • 张建宇. 2022-08-04 15:39
    关注

    看下引入的材质是否正确

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

问题事件

  • 系统已结题 8月30日
  • 已采纳回答 8月22日
  • 创建了问题 8月4日

悬赏问题

  • ¥20 西门子S7-Graph,S7-300,梯形图
  • ¥50 用易语言http 访问不了网页
  • ¥50 safari浏览器fetch提交数据后数据丢失问题
  • ¥15 matlab不知道怎么改,求解答!!
  • ¥15 永磁直线电机的电流环pi调不出来
  • ¥15 用stata实现聚类的代码
  • ¥15 请问paddlehub能支持移动端开发吗?在Android studio上该如何部署?
  • ¥20 docker里部署springboot项目,访问不到扬声器
  • ¥15 netty整合springboot之后自动重连失效
  • ¥15 悬赏!微信开发者工具报错,求帮改