本文目录
- 前言
- 一、模型类型
- 1.1 支持的模型类型
- 1.2 模型加载器
- 二、常用模型加载器
- 2.1 代码示例
- 2.1.1 GLTFLoader
- 2.1.1.1 代码
- 2.1.1.2 效果
前言
Three.js
是一个基于WebGL
的JavaScript 3D
库,它提供了丰富的API
来在网页上创建和显示 3D 图形。加载 3D 模型到Three.js
场景中是一个常见的需求,Three.js
支持多种格式的 3D 模型,如.glb(GL Transmission Format Binary)
、.gltf(GL Transmission Format)
、.obj
、.fbx
等。下面将简要介绍如何使用Three.js
加载 3D 模型。
一、模型类型
1.1 支持的模型类型
Three.js
支持加载多种模型文件格式,常见的包括:
glTF (.gltf .glb)
:glTF (GL Transmission Format)
是一种新型3D模型传输格式,具有高效、紧凑、支持PBR
材质等优点,是三维模型的标准格式。OBJ(.obj)
:OBJ
是一种广泛使用的3D模型格式,支持几何体和材质信息,但不支持动画。FBX(.fbx)
:FBX
支持几何体、材质、骨骼动画等丰富信息,常用于3D内容制作和动画。Collada (.dae)
:Collada
支持几何体、材质、动画等丰富信息。PLY (.ply)
:PLY (Polygon File Format或Stanford Triangle Format)
是一种用于存储3D扫描数据的格式,支持几何体和属性信息。STL(.stI)
:STL (Stereolithography)
是一种广泛用于3D打印的格式,主要支持几何体信息。VRML(.wrl)
:VRML (Virtual Reality Modeling Language)
是一种早期的3D模型格式,支持几何体、材质和简单动画。3DS (.3ds)3DS
:是Autodesk 3D Studio
的格式,支持几何体、材质和简单动画。JSON (.json)
:Three.js
的JSON
格式是一种自定义的模型格式,支持几何体材质、动画等信息。
1.2 模型加载器
Three.js
提供了多种的加载器来加载以上的模型。例如:
GLTF加载器(GLTFLoader)
:glTF
是专为高效传输与加载3D内容设计的开放格式,支持(.gltf
)与二进制(.glb
)格式。它整合了网格、材质、贴图、动画等丰富元素,并允许外部存储图像与数据,实现场景与资源的灵活传输。OBJ加载器(OBJLoader)
:OBJ
加载器处理3D几何数据,支持(.obj)格式。以易读方式存储顶点位置、
UV`坐标、法线及多边形信息,简化3D模型的加载过程。FBX加载器(FBXLoader)
:FBX
是一种广泛使用的3D模型文件格式,支持(.fbx
)格式。它可以包含几何形状、材质、动画、骨骼等多种数据,因此在游戏开发、虚拟现实、电影制作等领域有着广泛的应用。DAE加载器(ColladaLoader)
:用于加载和处理Collada(.dae)
格式3D模型文件的扩展。Collada
是一种基于XML
的3D内容格式,广泛用于三维软件和渲染引擎中,因为它不仅定义了模型的几何体,还包含了材质、光源等多种信息。PLY加载器(PLYLoader)
:用于加载PLY
(Polygon File Format
,多边形文件格式)格式3D模型文件的加载器。支持(.ply
)格式。PLY
格式主要用于存储简单的3D几何数据,包括顶点、颜色、法线和UV
坐标等,支持二进制和ASCII
格式。STL加载器(STLLoader)
:用于加载STL
(Stereolithography
,立体成型术)文件的类。STL
文件广泛用于3D打印和计算机辅助设计(CAD
)应用程序中,支持(.stl
)格式。它包含了模型的几何信息,但通常不包含材质、颜色或纹理信息。WRL加载器(VRMLLoader)
:用于加载VRML
(Virtual Reality Modeling Language
,虚拟现实建模语言)文件的加载器。支持(.wrl
)格式。尽管VRML是一种较老的、基于文本的格式,用于定义三维对象和世界,但它在某些特定场合或历史项目中仍然有其应用价值。3DS加载器(TDSLoader)
:用于加载3DS
(3D Studio
)文件的加载器。3DS
文件是由Autodesk
的3ds Max
软件创建的三维模型文件,它包含了模型的几何形状、材质、动画等信息。JSON加载器(JSONLoader)
:用于加载JSON
格式3D模型文件的加载器。JSON(JavaScript Object Notation)
是一种轻量级的数据交换格式,易于人阅读和编写,同时也易于机器解析和生成。
二、常用模型加载器
2.1 代码示例
2.1.1 GLTFLoader
2.1.1.1 代码
构造函数
GLTFLoader( filepath, gltfCallback, progressCallback, errorCallback )
代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
html,
body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
}
</style>
</head>
<body>
<script type="module">
// 倒入轨道控制器
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
import * as THREE from 'three';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader';
// 创建场景
const scene = new THREE.Scene();
scene.background = new THREE.Color(0xffffff);
// 创建相机
const camera = new THREE.PerspectiveCamera( // 透视相机
45, // 视角 角度数
window.innerWidth / window.innerHeight, // 宽高比 占据屏幕
0.1, // 近平面(相机最近能看到物体)
1000, // 远平面(相机最远能看到物体)
);
camera.position.set(0, 2, 40);
// 创建渲染器
const renderer = new THREE.WebGLRenderer({
antialias: true, // 抗锯齿
});
// 设置渲染器宽高
renderer.setSize(window.innerWidth, window.innerHeight);
// renderer(渲染器)的dom元素添加到我们的HTML文档中
document.body.appendChild(renderer.domElement);
// 加入灯光
const light = new THREE.PointLight(0xffffff, 900, 100);
light.position.set(20, 20, 10);
const pointLightHelper = new THREE.PointLightHelper(light, 3);
scene.add(pointLightHelper);
scene.add(light);
const ambientLight = new THREE.AmbientLight(0x404040, 100); // 柔和的白光
scene.add(ambientLight);
// 地面
const plane = new THREE.Mesh(
new THREE.PlaneGeometry(80, 80),
new THREE.MeshStandardMaterial({ color: 0x817936 })
);
plane.rotation.x = -Math.PI / 2;
// 添加到场景中
scene.add(plane);
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap; // 更好的阴影质量
renderer.shadowMap.needsUpdate = true;
plane.receiveShadow = true;
light.castShadow = true;
// 导入模型
const gltfLoader = new GLTFLoader();
gltfLoader.load("../models/pingzi.glb", (gltf) => {
console.log(gltf.scene.traverse);
// 设置模型的材质以接受阴影
gltf.scene.traverse((child) => {
if (child.isMesh) {
console.log(child)
child.castShadow = true; // 让模型产生阴影
// child.receiveShadow = true; // 让模型接受阴影
}
});
// 设置模型缩放
gltf.scene.scale.set(0.1, 0.1, 0.1);
// 设置模型位置
gltf.scene.position.set(0, 5.5, 0);
scene.add(gltf.scene);
},
// called while loading is progressing
(xhr) => {
console.log((xhr.loaded / xhr.total * 100) + '% loaded');
},
// called when loading has errors
(error) => {
console.log('An error happened', error);
})
// 控制器
const control = new OrbitControls(camera, renderer.domElement);
// 开启阻尼惯性,默认值为0.05
control.enableDamping = true;
// 渲染循环动画
function animate() {
// 在这里我们创建了一个使渲染器能够在每次屏幕刷新时对场景进行绘制的循环(在大多数屏幕上,刷新率一般是60次/秒)
requestAnimationFrame(animate);
// 更新控制器。如果没在动画里加上,那必须在摄像机的变换发生任何手动改变后调用
control.update();
renderer.render(scene, camera);
};
// 执行动画
animate();
</script>
</body>
</html>
2.1.1.2 效果
可以看到我们就把.glb
后缀多模型文件加载进来了,它是一个玻璃瓶子。
在学习的路上,如果你觉得本文对你有所帮助的话,那就请关注点赞评论三连吧,谢谢,你的肯定是我写博的另一个支持。