前端组件库 ——Three.js 知识点大全(二)

简介: 教程来源 http://www.detxg.cn/ Three.js核心组件包括几何体(定义形状)、材质(控制外观)、光源(营造光照)、相机(设定视角);高级功能涵盖纹理贴图、动画系统、模型加载(glTF)、粒子系统与射线检测,辅以几何合并、BufferGeometry使用、帧率控制等性能优化策略。

三、核心组件详解

3.1 几何体(Geometry / BufferGeometry)
几何体定义了物体的形状,它由顶点(vertices)和面(faces)组成。Three.js 提供了大量预置的几何体,方便快速构建基础形状。

Three.js 提供了丰富的内置几何体:
image.png

// 立方体
const boxGeometry = new THREE.BoxGeometry(2, 2, 2);
// 球体:半径1,宽度分段32,高度分段32
const sphereGeometry = new THREE.SphereGeometry(1, 32, 32);
// 圆柱体:顶半径1,底半径1,高度2
const cylinderGeometry = new THREE.CylinderGeometry(1, 1, 2, 32);
// 圆锥体:底半径1,高度2
const coneGeometry = new THREE.ConeGeometry(1, 2, 32);
// 平面:宽4,高4
const planeGeometry = new THREE.PlaneGeometry(4, 4);
// 甜甜圈:半径1,管半径0.4
const torusGeometry = new THREE.TorusGeometry(1, 0.4, 16, 100);

当预置的几何体无法满足需求时,可以通过自定义顶点来创建任意形状:

// 创建自定义几何体 - 三角形
const geometry = new THREE.BufferGeometry();
// 定义顶点位置(3个顶点,每个顶点有x,y,z坐标)
const vertices = new Float32Array([
    0, 1, 0,   // 顶点1 (上)
    -1, -1, 0, // 顶点2 (左下)
    1, -1, 0   // 顶点3 (右下)
]);
geometry.setAttribute('position', new THREE.BufferAttribute(vertices, 3));
// 定义面的颜色(可选)
const colors = new Float32Array([
    1, 0, 0,  // 红色
    0, 1, 0,  // 绿色
    0, 0, 1   // 蓝色
]);
geometry.setAttribute('color', new THREE.BufferAttribute(colors, 3));

3.2 材质(Material)
材质决定了物体表面的外观,包括颜色、纹理、光泽度、透明度等属性。
image.png

// 标准材质(最常用)
const standardMaterial = new THREE.MeshStandardMaterial({
    color: 0xff6600,
    roughness: 0.3,    // 粗糙度 0-1,值越小表面越光滑
    metalness: 0.7,    // 金属感 0-1,值越高越像金属
    emissive: 0x000000,// 自发光颜色
    emissiveIntensity: 0,
    flatShading: false,// 是否使用平面着色(显示棱角)
    side: THREE.FrontSide  // 渲染哪一面:FrontSide(正面)、BackSide(背面)、DoubleSide(双面)
});

// 基础材质(不受光照影响)
const basicMaterial = new THREE.MeshBasicMaterial({ color: 0xff0000 });

// 使用纹理图片作为材质
const textureLoader = new THREE.TextureLoader();
const woodTexture = textureLoader.load('wood.jpg');
const woodMaterial = new THREE.MeshStandardMaterial({ map: woodTexture });

3.3 光源(Light)
光源照亮物体,产生真实的立体感和阴影效果。
image.png

// 环境光:均匀照亮
const ambientLight = new THREE.AmbientLight(0x404040, 0.6); // 颜色、强度

// 平行光:模拟太阳
const directionalLight = new THREE.DirectionalLight(0xffffff, 1);
directionalLight.position.set(5, 10, 7);
directionalLight.castShadow = true;
// 配置阴影参数
directionalLight.shadow.mapSize.width = 1024;
directionalLight.shadow.mapSize.height = 1024;
directionalLight.shadow.camera.near = 0.5;
directionalLight.shadow.camera.far = 20;
directionalLight.shadow.camera.left = -5;
directionalLight.shadow.camera.right = 5;
directionalLight.shadow.camera.top = 5;
directionalLight.shadow.camera.bottom = -5;
scene.add(directionalLight);

// 点光源:灯泡效果
const pointLight = new THREE.PointLight(0xff6600, 0.8);
pointLight.position.set(2, 3, 4);
pointLight.castShadow = true;
scene.add(pointLight);

// 聚光灯:舞台灯光效果
const spotLight = new THREE.SpotLight(0xffffff, 1);
spotLight.position.set(0, 5, 2);
spotLight.castShadow = true;
spotLight.angle = Math.PI / 4;    // 光锥角度
spotLight.penumbra = 0.3;         // 边缘柔和度
spotLight.distance = 20;          // 照射距离
scene.add(spotLight);

3.4 相机(Camera)
相机决定了观察场景的视角和方式。

透视相机(PerspectiveCamera)是最常用的相机,模拟人眼视觉效果:

// 透视相机:视野角度FOV、宽高比、近平面、远平面
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.set(5, 5, 10);
camera.lookAt(0, 0, 0);

正交相机(OrthographicCamera)产生平行投影,无近大远小效果,常用于 2D 场景:

// 正交相机:左、右、上、下、近平面、远平面
const size = 5;
const camera = new THREE.OrthographicCamera(-size, size, size, -size, 0.1, 100);
camera.position.set(5, 5, 10);
camera.lookAt(0, 0, 0);

四、高级概念

4.1 纹理与贴图
纹理是将图像贴在物体表面,增强真实感的重要手段。

// 创建纹理加载器
const textureLoader = new THREE.TextureLoader();

// 加载基础颜色贴图
const colorMap = textureLoader.load('texture.jpg');

// 加载法线贴图(用于增加凹凸感)
const normalMap = textureLoader.load('normal.jpg');

// 加载高光贴图(控制反光区域)
const specularMap = textureLoader.load('specular.jpg');

// 加载环境遮挡贴图(控制阴影深度)
const aoMap = textureLoader.load('ao.jpg');

// 创建材质并应用纹理
const material = new THREE.MeshStandardMaterial({
    map: colorMap,
    normalMap: normalMap,
    roughnessMap: specularMap,
    aoMap: aoMap,
    roughness: 0.5,
    metalness: 0.6
});

4.2 动画系统
Three.js 提供了两种主要方式来实现动画:

  1. 直接修改物体属性(逐帧动画)

    function animate() {
     // 平移
     cube.position.x += 0.01;
    
     // 旋转
     cube.rotation.y += 0.02;
    
     // 缩放
     cube.scale.setScalar(1 + Math.sin(Date.now() * 0.002) * 0.1);
    
     requestAnimationFrame(animate);
    }
    
  2. 使用 AnimationMixer(骨骼动画/复杂动画)
    ```
    import { AnimationMixer } from 'three';

// 加载带动画的模型
const loader = new GLTFLoader();
loader.load('model.glb', (gltf) => {
const mixer = new AnimationMixer(gltf.scene);
const action = mixer.clipAction(gltf.animations[0]);
action.play();

function animate() {
    mixer.update(0.016); // 约60fps更新一次
    requestAnimationFrame(animate);
}
animate();

});

**4.3 模型加载**
Three.js 支持多种 3D 模型格式,最常用的是 glTF(GL Transmission Format),它是 Web 3D 模型的标准格式。

import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';

const loader = new GLTFLoader();
loader.load('model.glb',
(gltf) => {
// 模型加载成功
const model = gltf.scene;
model.scale.set(1, 1, 1);
model.position.set(0, 0, 0);
scene.add(model);

    // 播放动画(如果模型包含动画)
    if (gltf.animations.length) {
        const mixer = new THREE.AnimationMixer(model);
        gltf.animations.forEach((clip) => {
            mixer.clipAction(clip).play();
        });
    }
},
(xhr) => {
    // 加载进度
    const percent = (xhr.loaded / xhr.total) * 100;
    console.log(`模型加载进度: ${percent}%`);
},
(error) => {
    // 加载失败
    console.error('模型加载失败:', error);
}

);

**4.4 粒子系统**
粒子系统用于创建大量微小对象的效果,如星空、雪花、火花等。

// 创建粒子几何体
const particlesGeometry = new THREE.BufferGeometry();
const particleCount = 5000;

// 随机生成粒子位置
const positions = new Float32Array(particleCount 3);
for (let i = 0; i < particleCount; i++) {
positions[i
3] = (Math.random() - 0.5) 200;
positions[i
3+1] = (Math.random() - 0.5) 100;
positions[i
3+2] = (Math.random() - 0.5) * 100;
}
particlesGeometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));

// 创建粒子材质
const particlesMaterial = new THREE.PointsMaterial({
color: 0x88aaff,
size: 0.2,
transparent: true,
opacity: 0.8,
blending: THREE.AdditiveBlending // 添加混合模式,产生发光效果
});

// 创建粒子系统
const particles = new THREE.Points(particlesGeometry, particlesMaterial);
scene.add(particles);

// 让粒子系统缓慢旋转
function animate() {
particles.rotation.y += 0.001;
particles.rotation.x += 0.0005;
requestAnimationFrame(animate);
}

**4.5 射线检测(Raycaster)**
射线检测用于实现点击选择物体、拾取交互等功能。

// 创建射线检测器
const raycaster = new THREE.Raycaster();
const mouse = new THREE.Vector2();

// 监听鼠标点击事件
window.addEventListener('click', (event) => {
// 计算鼠标位置归一化坐标(范围 -1 到 +1)
mouse.x = (event.clientX / renderer.domElement.clientWidth) 2 - 1;
mouse.y = -(event.clientY / renderer.domElement.clientHeight)
2 + 1;

// 通过相机和鼠标位置更新射线
raycaster.setFromCamera(mouse, camera);

// 检测与物体的交点
const intersects = raycaster.intersectObjects(objects);

if (intersects.length > 0) {
    // 选中了第一个相交的物体
    const selected = intersects[0].object;
    console.log('选中物体:', selected);
    // 高亮选中的物体
    selected.material.emissive.setHex(0xff6600);
}

});

# 五、性能优化
**5.1 几何体合并**
对于大量静态物体,可以将它们的几何体合并成一个,减少绘制调用次数。

// 只需导入必要的组件,减少体积
import { BoxGeometry, MeshStandardMaterial, Mesh, Scene } from 'three';

**5.2 使用 BufferGeometry**
BufferGeometry 比 Geometry 性能更好,推荐使用。

**5.3 限制帧率**
对于不需要高帧率的应用,可以限制动画帧率以节省资源。

let lastTime = 0;
const fps = 30;
const interval = 1000 / fps;

function animate(currentTime) {
requestAnimationFrame(animate);
const delta = currentTime - lastTime;
if (delta < interval) return;

lastTime = currentTime - (delta % interval);
// 更新逻辑...

}

**5.4 阴影优化**
阴影计算开销较大,可以通过以下方式优化:

// 降低阴影贴图分辨率
directionalLight.shadow.mapSize.width = 512;
directionalLight.shadow.mapSize.height = 512;

// 限制阴影投射范围
directionalLight.shadow.camera.near = 0.5;
directionalLight.shadow.camera.far = 12;
directionalLight.shadow.camera.left = -5;
directionalLight.shadow.camera.right = 5;
directionalLight.shadow.camera.top = 5;
directionalLight.shadow.camera.bottom = -5;

// 只为重要物体开启阴影
cube.castShadow = true; // 立方体投射阴影
plane.receiveShadow = true; // 平面接收阴影

**5.5 资源释放**
及时释放不需要的资源,防止内存泄漏:

// 释放几何体
geometry.dispose();

// 释放材质
material.dispose();

// 释放纹理
texture.dispose();

// 从场景中移除物体
scene.remove(object);
```
来源:
http://detxg.cn/

相关文章
|
8天前
|
缓存 人工智能 自然语言处理
我对比了8个Claude API中转站,踩了不少坑,总结给你
本文是个人开发者耗时1周实测的8大Claude中转平台横向评测,聚焦Claude Code真实体验:以加权均价(¥/M token)、内部汇率、缓存支持、模型真实性及稳定性为核心指标。
3435 20
|
20天前
|
人工智能 自然语言处理 安全
Claude Code 全攻略:命令大全 + 实战工作流(建议收藏)
本文介绍了Claude Code终端AI助手的使用指南,主要内容包括:1)常用命令如版本查看、项目启动和更新;2)三种工作模式切换及界面说明;3)核心功能指令速查表,包含初始化、压缩对话、清除历史等操作;4)详细解析了/init、/help、/clear、/compact、/memory等关键命令的使用场景和语法。文章通过丰富的界面截图和场景示例,帮助开发者快速掌握如何通过命令行和交互界面高效使用Claude Code进行项目开发,特别强调了CLAUDE.md文件作为项目知识库的核心作用。
17984 60
Claude Code 全攻略:命令大全 + 实战工作流(建议收藏)
|
1天前
|
SQL 人工智能 弹性计算
阿里云发布 Agentic NDR,威胁检测与响应进入智能体时代
欢迎前往阿里云云防火墙控制台体验!
1158 2
|
4天前
|
人工智能 JSON BI
DeepSeek V4 来了!超越 Claude Sonnet 4.5,赶紧对接 Claude Code 体验一把
JeecgBoot AI专题研究 把 Claude Code 接入 DeepSeek V4Pro 的真实体验与避坑记录 本文记录我将 Claude Code 对接 DeepSeek 最新模型(V4Pro)后的真实体验,测试了 Skills 自动化查询和积木报表 AI 建表两个场景——有惊喜,也踩
1857 8
|
15天前
|
人工智能 JavaScript Ubuntu
低成本搭建AIP自动化写作系统:Hermes保姆级使用教程,长文和逐步实操贴图
我带着怀疑的态度,深度使用了几天,聚焦微信公众号AIP自动化写作场景,写出来的几篇文章,几乎没有什么修改,至少合乎我本人的意愿,而且排版风格,也越来越完善,同样是起码过得了我自己这一关。 这个其实OpenClaw早可以实现了,但是目前我觉得最大的区别是,Hermes会自主总结提炼,并更新你的写作技能。 相信就冲这一点,就值得一试。 这篇帖子主要就Hermes部署使用,作一个非常详细的介绍,几乎一步一贴图。 关于Hermes,无论你赞成哪种声音,我希望都是你自己动手行动过,发自内心的选择!
3172 29
|
3天前
|
人工智能 缓存 BI
Claude Code + DeepSeek V4-Pro 真实评测:除了贵,没别的毛病
JeecgBoot AI专题研究 把 Claude Code 接入 DeepSeek V4Pro,跑完 Skills —— OA 审批、大屏、报表、部署 5 大实战场景后的真实体验 ![](https://oscimg.oschina.net/oscnet/up608d34aeb6bafc47f
1479 3
Claude Code + DeepSeek V4-Pro 真实评测:除了贵,没别的毛病
|
4天前
|
机器学习/深度学习 缓存 测试技术
DeepSeek-V4开源:百万上下文,Agent能力比肩顶级闭源模型
DeepSeek-V4正式开源!含V4-Pro(1.6T参数)与V4-Flash(284B参数)双版本,均支持百万token上下文。首创混合注意力架构,Agent能力、世界知识与推理性能全面领先开源模型,数学/代码评测比肩顶级闭源模型。
1737 6
|
5天前
|
人工智能 测试技术 API
阿里Qwen3.6-27B正式开源:网友直呼“太牛了”!
阿里云千问3.6系列重磅开源Qwen3.6-27B稠密大模型!官网:https://t.aliyun.com/U/JbblVp 仅270亿参数,编程能力媲美千亿模型,在SWE-bench等权威基准中表现卓越。支持多模态理解、本地部署及OpenClaw等智能体集成,已开放Hugging Face与ModelScope下载。