
threeJs初体验
教程:https://discoverthreejs.com/zh/book/first-steps/
场景,相机,渲染器,网格(几何体+材质) 重要的概念
要起一个web服务
shell
"three": "^0.173.0",
"vite": "^6.1.1",
"lil-gui": "^0.20.0",
threeJs小demo
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>My first three.js app</title>
</head>
<body>
<script type="module">
import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
// 1. 创建场景、相机和渲染器
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
const renderer = new THREE.WebGLRenderer();
// 2. 设置渲染器大小
renderer.setSize(window.innerWidth, window.innerHeight);
// 设置设备像素比(DPR)
renderer.setPixelRatio(window.devicePixelRatio);
// 3. 将渲染器的 DOM 元素添加到页面中
document.body.appendChild(renderer.domElement);
// 4. 创建几何体和材质,并添加到场景中
const geometry = new THREE.BoxGeometry();
//不收漫反射光源影响的材质
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
const cube = new THREE.Mesh(geometry, material);
scene.add(cube);
//坐标辅助线, 红绿蓝 代表 x y z
const axesHelper = new THREE.AxesHelper(150);
scene.add(axesHelper);
// 创建辅助网格
const size = 10; // 网格的大小
const divisions = 10; // 网格的分割线数量
const gridHelper = new THREE.GridHelper(size, divisions);
scene.add(gridHelper); // 将网格添加到场景中
// 5. 设置相机位置
camera.position.z = 5;
// 添加 OrbitControls
const controls = new OrbitControls(camera, renderer.domElement);
// 6. 渲染场景
function animate() {
requestAnimationFrame(animate);
cube.rotation.x += 0.01; // 旋转
cube.rotation.y += 0.01; // 旋转
renderer.render(scene, camera); // 渲染场景
// 更新控制器
controls.update();
}
animate(); // 启动动画循环
</script>
</body>
</html>
GUI小demo
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>My first three.js app</title>
<style>
body{
overflow: hidden;
margin: 0px;
}
</style>
</head>
<body>
<script type="module">
import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
// 引入dat.gui.js的一个类GUI
import { GUI } from 'lil-gui';
// 1. 创建场景、相机和渲染器
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
const renderer = new THREE.WebGLRenderer();
// 2. 设置渲染器大小
renderer.setSize(window.innerWidth, window.innerHeight);
// 设置设备像素比(DPR)
renderer.setPixelRatio(window.devicePixelRatio);
// 3. 将渲染器的 DOM 元素添加到页面中
document.body.appendChild(renderer.domElement);
// 4. 创建几何体和材质,并添加到场景中
const geometry = new THREE.BoxGeometry(5,5,5);
//MeshBasicMaterial:不受光照影响,MeshLambertMaterial受光照影响
const material = new THREE.MeshLambertMaterial({ color: 0x00ff00 });
const cube = new THREE.Mesh(geometry, material);
scene.add(cube);
//添加灯光 一个灯泡以灯泡为中心向四周发射光线
const pointLight = new THREE.PointLight(0xffffff, 30.0);
pointLight.position.set(6,6,6)
scene.add(pointLight);
// 添加点光源助手 ,第二个参数代表光源助手的尺寸大小
const pointLightHelper = new THREE.PointLightHelper(pointLight, 0.1);
scene.add(pointLightHelper);
// DirectionalLightHelper:可视化平行光 辅助观察对象
// const dirLightHelper = new THREE.DirectionalLightHelper(pointLight, 5,0xff0000);
// scene.add(dirLightHelper);
const gui = new GUI(); //创建GUI对象
const obj = {
color: 0x00ffff,// 材质颜色
};
// 创建材质子菜单
const matFolder = gui.addFolder('材质');
// 材质颜色color
matFolder.addColor(obj, 'color').onChange(function(value){
material.color.set(value);
});
//坐标辅助线, 红绿蓝 代表 x y z , 150表示辅助线的长度
const axesHelper = new THREE.AxesHelper(150);
scene.add(axesHelper);
// 创建辅助网格
const size = 10; // 网格的大小
const divisions = 10; // 网格的分割线数量
const gridHelper = new THREE.GridHelper(size, divisions);
scene.add(gridHelper); // 将网格添加到场景中
// 5. 设置相机位置
camera.position.z = 5;
// 添加 OrbitControls
const controls = new OrbitControls(camera, renderer.domElement);
// 6. 渲染场景
function animate() {
requestAnimationFrame(animate);
// cube.rotation.x += 0.01; // 旋转
cube.rotation.y += 0.01; // 旋转
renderer.render(scene, camera); // 渲染场景
// 更新控制器
controls.update();
}
animate(); // 启动动画循环
// // 如果OrbitControls改变了相机参数,重新调用渲染器渲染三维场景
// renderer.render(scene, camera); // 渲染场景
// //监听鼠标、键盘事件
// controls.addEventListener('change', function () {
// renderer.render(scene, camera); //执行渲染操作
// });
</script>
</body>
</html>
贴图
js
//纹理贴图加载器TextureLoader
const texLoader = new THREE.TextureLoader();
// .load()方法加载图像,返回一个纹理对象Texture
const texture = texLoader.load('../2.png');
const material = new THREE.MeshLambertMaterial({
// 设置纹理贴图:Texture对象作为材质map属性的属性值
map: texture,//map表示材质的颜色贴图属性
});
加载3D模型
3D模型资源网站:https://sketchfab.com/3d-models?features=downloadable&sort_by=-likeCount
js
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader'
const loader = new GLTFLoader()
const dracoLoader = new DRACOLoader()
dracoLoader.setDecoderPath('https://threejs.org/examples/jsm/libs/draco/')
dracoLoader.preload()
loader.setDRACOLoader(dracoLoader)
loader.load('https://threejs.org/examples/models/gltf/LittlestTokyo.glb', (gltf) => {
scene.add(gltf.scene)
renderer.render(scene, camera)
}, (xhr) => {
console.log((xhr.loaded / xhr.total) * 100 + '% loaded')
}, (error) => {
console.error(error)
})
- GLTFLoader : 加载GLTF加载器,glTF(gl传输格式)是一种开放格式的规范 (open format specification), 用于更高效地传输、加载3D内容。该类文件以JSON(.gltf)格式或二进制(.glb)格式提供, 外部文件存储贴图(.jpg、.png)和额外的二进制数据(.bin)
- OrbitControls : 轨道控制器(OrbitControls)Orbit controls(轨道控制器)可以使得相机围绕目标进行轨道运动。
- DRACOLoader : 一个加载器的几何压缩与Draco库。Draco是一个开源库,用于压缩和解压缩3D网格和点云。压缩后的几何图形可以显著变小,代价是在客户端设备上花费额外的解码时间。
v1.5.2