Three.js - 加载 .OBJ 格式模型(十六)

.obj

  • obj文件是3D模型文件格式。
  • 它包含的信息都是几何体顶点相关数据,不包含动画、材质特性、粒子等信息。

使用

  • 第一步当然是找UI设计要文件了,这里没有UI就自己到网上下载了一个文件。
  • 创建基础代码,这里使用方向光和半球光让模型更立体。
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>学习</title>
  </head>
  <body>
    <canvas id="c2d" class="c2d" width="1000" height="500"></canvas>
    <script type="module">
      import * as THREE from './file/three.js-dev/build/three.module.js'
      import { OrbitControls } from './file/three.js-dev/examples/jsm/controls/OrbitControls.js'

      const canvas = document.querySelector('#c2d')
      // 渲染器
      const renderer = new THREE.WebGLRenderer({ canvas })

      const fov = 40 // 视野范围
      const aspect = 2 // 相机默认值 画布的宽高比
      const near = 0.1 // 近平面
      const far = 1000 // 远平面
      // 透视投影相机
      const camera = new THREE.PerspectiveCamera(fov, aspect, near, far)
      camera.position.set(0, 50, 0)
      camera.lookAt(0, 0, 0)
      // 控制相机
      const controls = new OrbitControls(camera, canvas)
      controls.update()

      // 场景
      const scene = new THREE.Scene()
      scene.background = new THREE.Color('black')

      {
        // 半球光
        const skyColor = 0xb1e1ff // 蓝色
        const groundColor = 0xffffff // 白色
        const intensity = 1
        const light = new THREE.HemisphereLight(skyColor, groundColor, intensity)
        scene.add(light)
      }

      {
        // 方向光
        const color = 0xffffff
        const intensity = 1
        const light = new THREE.DirectionalLight(color, intensity)
        light.position.set(0, 10, 0)
        light.target.position.set(-5, 0, 0)
        scene.add(light)
        scene.add(light.target)
      }

      // 渲染
      function render() {
        renderer.render(scene, camera)
        requestAnimationFrame(render)
      }

      requestAnimationFrame(render)
    </script>
  </body>
</html>
  • 引入官方插件OBJLoader解析文件。
import { OBJLoader } from './file/three.js-dev/examples/jsm/loaders/OBJLoader.js'
  • 创建实例。通过url加载.obj文件,并在回调函数中将已加载完的模型添加到场景里。
      {
        const objLoader = new OBJLoader()
        objLoader.load('./file/windmill/windmill.obj', (root) => {
          scene.add(root)
        })
      }

1.gif

  • 这里我们可以看到模型已经加载完毕,不过模型颜色是白色的。

加载.mtl文件

  • 因为.obj文件是没有材质信息的,我们还需要加载一个和它配套的.mtl文件。

image.png

  • 每一个newmtl Material代表一个材质信息,这里有两个材质。材质里面使用了图片,图片需要和文件在同级目录。
  • 首先要引用 MTLLoader解析文件。
import { MTLLoader } from './file/three.js-dev/examples/jsm/loaders/MTLLoader.js'
  • 然后实例化,加载.mtl文件。通过OBJLoader的方法.setMaterials()加载材质。
      {
        const mtlLoader = new MTLLoader()
        mtlLoader.load('./file/windmill/windmill.mtl', (mtl) => {
          mtl.preload()
          const objLoader = new OBJLoader()
          objLoader.setMaterials(mtl)

          // 加载模型
          objLoader.load('./file//windmill/windmill.obj', (root) => {
            scene.add(root)
          })
        })
      }

1.gif

修改材质

  • 通过MTLLoader对象的.materials属性获取材质。
for (const material of Object.values(mtl.materials)) {
    console.log('material', material)
    // 设置材质双面
    material.side = THREE.DoubleSide
}

image.png

  • 解析完成后,就是创建的一个材质对象,我们可以正常对这个材质对象修改。

总结

一般情况下我们都会使用模型进行开发,用代码绘制图像会浪费大量时间。除.OBJ格式,还有很多其他格式的模型。当然我们都是使用官方插件进行加载,不过插件不同代表对象的属性不同,使用的方式就会有差异。
这里我遇到一个问题,就是插件的版本和three.js的版本不一致,导致THREE对象缺少方法。这里我把官网代码下载了一份到本地。
在根目录使用 npx http-server,启动本地服务器,加载本地资源和同版本插件。

资源地址

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值