.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)
})
}
- 这里我们可以看到模型已经加载完毕,不过模型颜色是白色的。
加载.mtl文件
- 因为
.obj
文件是没有材质信息的,我们还需要加载一个和它配套的.mtl
文件。
- 每一个
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)
})
})
}
修改材质
- 通过
MTLLoader
对象的.materials
属性获取材质。
for (const material of Object.values(mtl.materials)) {
console.log('material', material)
// 设置材质双面
material.side = THREE.DoubleSide
}
- 解析完成后,就是创建的一个材质对象,我们可以正常对这个材质对象修改。
总结
一般情况下我们都会使用模型进行开发,用代码绘制图像会浪费大量时间。除.OBJ格式,还有很多其他格式的模型。当然我们都是使用官方插件进行加载,不过插件不同代表对象的属性不同,使用的方式就会有差异。
这里我遇到一个问题,就是插件的版本和three.js的版本不一致,导致THREE对象缺少方法。这里我把官网代码下载了一份到本地。
在根目录使用 npx http-server
,启动本地服务器,加载本地资源和同版本插件。