「这是我参与2022首次更文挑战的第16天,活动详情查看:2022首次更文挑战」
.obj
obj文件是3D模型文件格式。
它包含的信息都是几何体顶点相关数据,不包含动画、材质特性、粒子等信息。
使用
第一步当然是找UI设计要文件了,这里没有UI就自己到网上下载了一个文件。
创建基础代码,这里使用方向光和半球光让模型更立体。
学习
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)
引入官方插件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](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/2f1530b4f3854dd7b3f17951036536ac~tplv-k3u1fbpfcp-zoom-in-crop-mark:1512:0:0:0.awebp?)
这里我们可以看到模型已经加载完毕,不过模型颜色是白色的。
加载.mtl文件
因为.obj文件是没有材质信息的,我们还需要加载一个和它配套的.mtl文件。
![image.png](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/54890b6d1106421aa99748b19699b3c0~tplv-k3u1fbpfcp-zoom-in-crop-mark:1512:0:0:0.awebp?)
每一个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](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/032e968e02764b3f9e65d57356f907ee~tplv-k3u1fbpfcp-zoom-in-crop-mark:1512:0:0:0.awebp?)
修改材质
通过MTLLoader对象的.materials属性获取材质。
for (const material of Object.values(mtl.materials)) {
console.log('material', material)
// 设置材质双面
material.side = THREE.DoubleSide
}
![image.png](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/2738251158a541d7ae0891cf9f8c83f5~tplv-k3u1fbpfcp-zoom-in-crop-mark:1512:0:0:0.awebp?)
解析完成后,就是创建的一个材质对象,我们可以正常对这个材质对象修改。
总结
一般情况下我们都会使用模型进行开发,用代码绘制图像会浪费大量时间。除.OBJ格式,还有很多其他格式的模型。当然我们都是使用官方插件进行加载,不过插件不同代表对象的属性不同,使用的方式就会有差异。
这里我遇到一个问题,就是插件的版本和three.js的版本不一致,导致THREE对象缺少方法。这里我把官网代码下载了一份到本地。
在根目录使用 npx http-server,启动本地服务器,加载本地资源和同版本插件。
资源地址
|