在 Three.js 中,材质(Material) 和 光照(Light) 是 3D 场景视觉效果的核心。合理搭配材质和光照,可以让物体 真实反光、透明、金属感、卡通效果 等。
🎯 1. 材质(Material)分类
Three.js 提供了多种材质,每种材质适用于不同的效果:
材质类型 |
适用场景 |
特点 |
是否受光照影响 |
|
纯色/纹理 |
不受光照影响 |
❌ |
|
PBR 物理材质(推荐) |
支持 金属、粗糙度 |
✅ |
|
高级 PBR 材质 |
透明、清漆、次表面散射 |
✅ |
|
低成本光照 |
无高光,计算漫反射 |
✅ |
|
经典光照材质 |
支持 高光(specular) |
✅ |
|
卡通渲染 |
类似 2D 动漫 |
✅ |
|
深度缓冲材质 |
用于 阴影、后处理 |
❌ |
|
预烘焙材质 |
不受光照影响,依赖 MatCap 贴图 |
❌ |
🎯 2. 常见材质属性
所有材质都继承自 THREE.Material
,但有些属性只适用于特定材质。
属性 |
作用 |
适用材质 |
|
颜色纹理 |
所有材质(除 Depth、Matcap) |
|
颜色 |
所有材质 |
|
透明度 |
才生效 |
|
是否透明 |
所有材质 |
|
正面/背面/双面 |
|
|
线框模式 |
所有材质 |
|
金属度( ) |
|
|
粗糙度( ) |
|
|
高光强度 |
|
|
高光颜色 |
|
|
是否平面着色 |
让模型棱角分明 |
|
位移贴图(改变顶点高度) |
|
|
法线贴图(增加凹凸感) |
|
|
环境遮蔽贴图(增强阴影) |
|
|
环境贴图(反射环境) |
|
🎯 3. 纹理贴图(Texture)
材质可以使用多种 贴图(Texture) 来增强视觉效果:
纹理贴图 |
作用 |
适用材质 |
|
基础颜色贴图 |
✅ |
|
透明度(黑色透明) |
✅ |
|
凹凸贴图 |
|
|
法线贴图 |
|
|
粗糙度贴图 |
|
|
金属度贴图 |
|
|
环境遮蔽(阴影) |
|
|
自发光贴图 |
|
const material = new THREE.MeshStandardMaterial({
map: colorTexture, // 颜色贴图
normalMap: normalTexture, // 法线贴图
roughnessMap: roughnessTexture, // 粗糙度贴图
metalnessMap: metalnessTexture, // 金属度贴图
aoMap: ambientOcclusionTexture, // AO 贴图
displacementMap: heightTexture, // 位移贴图
displacementScale: 0.1, // 位移强度
transparent: true,
side: THREE.DoubleSide,
});
🎯 4. 光照(Lighting)
在 Three.js 中,某些材质需要 光源 才能正确显示,比如 MeshStandardMaterial
。
🔹 环境光(AmbientLight)
- 不产生阴影,均匀照亮整个场景
- 适用于基础填充光
const ambientLight = new THREE.AmbientLight(0xffffff, 1);
scene.add(ambientLight);
🔹 点光源(PointLight)
- 类似灯泡,从一个点向四周发光
- 可以产生阴影
const pointLight = new THREE.PointLight(0xffffff, 30);
pointLight.position.set(2, 3, 4);
scene.add(pointLight);
🔹 平行光(DirectionalLight)
- 类似太阳光,从固定方向照射
- 适用于户外场景
const directionalLight = new THREE.DirectionalLight(0xffffff, 1);
directionalLight.position.set(5, 5, 5);
scene.add(directionalLight);
🔹 聚光灯(SpotLight)
- 类似手电筒,有方向性
const spotLight = new THREE.SpotLight(0xffffff, 10);
spotLight.position.set(0, 5, 0);
scene.add(spotLight);
🎯 5. HDR 环境贴图
Three.js 支持 HDR 贴图 来增强场景光照与反射效果。
import { RGBELoader } from 'three/examples/jsm/loaders/RGBELoader.js';
const rgbeLoader = new RGBELoader();
rgbeLoader.load('textures/environment.hdr', (hdrTexture) => {
hdrTexture.mapping = THREE.EquirectangularReflectionMapping;
// 影响整个场景
scene.environment = hdrTexture;
scene.background = hdrTexture;
// 影响单个物体
material.envMap = hdrTexture;
material.needsUpdate = true;
});
✔ HDR 贴图能提供更真实的环境反射
✔ 需要设置 THREE.EquirectangularReflectionMapping
🎯 6. 鼠标拖动画面
Three.js 提供 OrbitControls 来让用户交互。
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
// 创建控件
const controls = new OrbitControls(camera, renderer.domElement);
controls.enableDamping = true; // 添加阻尼效果
controls.screenSpacePanning = false; // 限制平移方向
鼠标操作
鼠标操作 |
效果 |
左键拖动 |
旋转视角 |
右键拖动 |
平移相机 |
滚轮滚动 |
缩放 |
🎯 7. 调试 GUI
可以使用 dat.GUI
调整参数:
import * as dat from 'dat.gui';
const gui = new dat.GUI();
gui.add(material, 'metalness').min(0).max(1).step(0.01);
gui.add(material, 'roughness').min(0).max(1).step(0.01);
gui.add(material, 'aoMapIntensity').min(0).max(10).step(0.01);
这样可以 实时修改材质参数,方便调试。
🚀 总结
✔ MeshStandardMaterial
是最推荐的 PBR 材质
✔ 光照对不同材质的影响不同,基本材质 (MeshBasicMaterial
) 不受影响
✔ HDR 贴图能大幅提升环境反射效果
✔ OrbitControls
让鼠标控制视角