Three.js之加载外部三维模型

参考资料

  • 建模软件绘制3D场景
  • 加载.gltf文件(模型加载全流程)

知识点

注:基于Three.jsv0.155.0

  • 三维建模软件
  • gltf格式
  • 加载.gltf文件
  • OrbitControls辅助设置相机参数:相机位置、相机目标对象
  • gltf不同文件形式(.glb)
  • 模型命名(程序与美术协作):.getObjectByName()
  • 递归遍历层级模型修改材质:.traverse()
  • 外部模型材质是否共享的问题
  • 纹理encoding和渲染器
  • gltf模型更换.map(纹理.flipY)

三维建模软件

D美术常用的三维建模软件,比如Blender、3dmax、C4D、maya等等

  • Blender(轻量开源)
  • 3dmax
  • C4D
  • maya

特殊行业项目可能涉及到行业软件,比如机械相关、建筑相关

  • 机械相关:SW、UG等
  • 建筑相关:草图大师、revit

gltf格式

GLTF格式是新2015发布的三维模型格式,随着物联网、WebGL、5G的进一步发展,会有越来越多的互联网项目Web端引入3D元素,你可以把GLTF格式的三维模型理解为.jpg、.png格式的图片一样,现在的网站,图片基本是标配,对于以后的网站来说如果需要展示一个场景,使用3D来替换图片表达也是很正常的事情。图片有很多格式,对于三维模型自然也是如此,Web开发的时候图片会有常用格式,对于Web3D开发也一样,肯定会根据需要选择一个常见的大家都熟悉的格式,随时时间的发展,GLTF必然称为一个极为重要的标准格式。

不仅three.js,其它的WebGL三维引擎cesium、babylonjs都对gltf格式有良好的的支持。

gltf格式文件不一定就是以扩展名.gltf结尾,.glb就是gltf格式的二进制文件。比如你可以把.gltf模型和贴图信息全部合成得到一个.glb文件中,.glb文件相对.gltf文件体积更小,网络传输自然更快。

加载.gltf文件

  1. gltf模型加载器GLTFLoader.js
  2. 相机参数根据需要设置
  3. 加载gltf的时候,webgl渲染器编码方式设置
<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Three.js</title>
</head>
  <body>
  </body>
  <!-- 具体路径配置,你根据自己文件目录设置,我的是课件中源码形式 -->
  <script type="importmap">
    {
      "imports": {
        "three": "./js/three.module.js",
        "three/addons/": "../three.js/examples/jsm/"
      }
    }
  </script>
  <script type="module">
    import * as THREE from 'three';
    import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
    import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';

    const width = window.innerWidth
    const height = window.innerHeight

    // 场景
    const scene = new THREE.Scene();

    const textureLoader = new THREE.TextureLoader();
    const texture = textureLoader.load('./img/6.JPG');
    console.log('texture.flipY', texture.flipY);


    const loader = new GLTFLoader();
    // 加载工厂文件
    loader.load('assets/工厂.gltf', function(gltf) {
      // 模型
      const model = gltf.scene;
      console.log(' ~ file: 6.加载外部三维模型.html:34 ~ loader.load ~ model:', model)
      
      // 获取某个模型并改变材质颜色
      const water = model.getObjectByName('水面');
      water.material.map = texture;
      console.log(' ~ file: 6.加载外部三维模型.html:37 ~ loader.load ~ water:', water)

      // water.material = new THREE.MeshBasicMaterial({
      //   color: '#ffffff'
      // })
      // water.material.color.set('#ffffff');

      //遍历模型并改变材质颜色
      model.traverse(function(child){
        // 模型网格
        if(child.isMesh){
          // 网格材质
          child.material.color.set('#ffffff');
        }
      })

      scene.add(model);
    })

    // 点光源
    const pointLight = new THREE.PointLight( 0xffffff, 1.0, 0, 0);
    pointLight.position.set(200, 200, 200 );
    scene.add( pointLight );
    
    // 环境光
    const ambientLight = new THREE.AmbientLight( 0xffffff, 1);
    scene.add( ambientLight );

    // 坐标系
    const axes = new THREE.AxesHelper(200);
    scene.add(axes);

    // 相机
    const camera = new THREE.PerspectiveCamera(75, width/height, 0.1, 3000);
    camera.position.set(-49, 146, 35);
    camera.lookAt(-11, -51,  0.7);

    // 渲染器
    const renderer = new THREE.WebGLRenderer();
    renderer.setSize(width, height);
    renderer.render(scene, camera);
    document.body.appendChild(renderer.domElement);

    renderer.outputColorSpace = THREE.SRGBColorSpace;//设置为SRGB颜色空间

    const controls = new OrbitControls(camera, renderer.domElement);
    controls.target.set(-11, -51,  0.7);
    controls.update();//update()函数内会执行camera.lookAt(controls.targe)
    // Vector3 {x: -49.803731395661714, y: 146.90160246353028, z: 35.47368304973255}
    // Vector3 {x: -11.970638355445846, y: -51.0801205834488, z: 0.7429414745816755}
    // 渲染循环
    function render() {
        renderer.render(scene, camera);
        // console.log(' ~ file: 6.加载外部三维模型.html:70 ~ render ~ camera:', camera.position) // 鼠标左键改变相机位置
        // console.log(' ~ file: 6.加载外部三维模型.html:66 ~ controls:', controls.target) // 鼠标右键改变相机观察点
        requestAnimationFrame(render);
    }
    render();

    // 控制器

    controls.addEventListener('change', () => {
      // 因为动画渲染了,所以这里可以省略
      renderer.render(scene, camera);
    });
  </script>
</html>

你可能感兴趣的:(Web3D,Web3D,threejs)