Three.js 材质(Material)详解 —— 区别、原理、场景与示例

一、概念

在 Three.js 中,材质(Material)决定了几何体表面的外观------包括颜色、光照反应、透明度、反射率、甚至物理属性。

简单来说,几何体是形状,材质是皮肤 。

不同的材质会模拟不同的现实渲染效果,从低成本的"纯色贴图",到高质量的 PBR(基于物理的渲染) 。


二、原理

材质的核心是 着色器(Shader) ,即 GPU 上运行的小程序。

Three.js 提供了两类材质:

  1. 内置材质 :如 MeshPhongMaterial、MeshStandardMaterial,直接调用,简单易用。
  2. 自定义材质 :如 ShaderMaterial、RawShaderMaterial,需要自己写 GLSL。

不同材质的底层实现基于不同的 光照模型:

  • Lambert(漫反射) → 粗糙表面,无镜面高光。
  • Phong(冯氏模型) → 漆面、陶瓷,带镜面反射。
  • Standard / Physical(PBR 模型) → 金属、玻璃、水,逼真模拟。

三、对比

材质 是否受光照影响 主要参数 适用场景 性能开销
SpriteMaterial 否 map, color 2D 图标、UI、特效 ★
ShadowMaterial 特殊 opacity 阴影接收 ★
ShaderMaterial 自定义 uniforms, vertex/fragmentShader 特效、波纹、火焰 ★★★★
RawShaderMaterial 自定义 完全自写 GLSL 高级渲染 ★★★★★
PointsMaterial 否 size, map 粒子系统、星空、点云 ★
MeshToonMaterial 是 gradientMap 卡通渲染、漫画风 ★★
MeshStandardMaterial 是 metalness, roughness, map 木材、金属、石头 ★★★
MeshPhysicalMaterial 是 transmission, clearcoat 玻璃、水、宝石 ★★★★
MeshPhongMaterial 是 shininess, specular 漆面、塑料 ★★
MeshNormalMaterial 否 无需参数 法线调试 ★
MeshLambertMaterial 是 color 布料、纸张 ★
MeshMatcapMaterial 否 matcap 纹理 ZBrush 风格快速预览 ★
MeshDistanceMaterial 特殊 near, far 阴影、深度编码 ★

四、实践(示例代码)

ini 复制代码
import * as THREE from 'three';

// 初始化场景
const scene = new THREE.Scene();

// 相机
const camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.set(0, 2, 10);

// 渲染器
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMap.enabled = true;
document.body.appendChild(renderer.domElement);

// 灯光
const light = new THREE.DirectionalLight(0xffffff, 1);
light.position.set(5, 5, 5);
light.castShadow = true;
scene.add(light);

// 地面接收阴影
const ground = new THREE.Mesh(
  new THREE.PlaneGeometry(20, 20),
  new THREE.ShadowMaterial({ opacity: 0.3 })
);
ground.rotation.x = -Math.PI / 2;
ground.receiveShadow = true;
scene.add(ground);

// 常见几何体
const geometry = new THREE.SphereGeometry(0.7, 32, 32);

// 各种材质
const materials = [
  new THREE.MeshBasicMaterial({ color: 0xff0000 }),
  new THREE.MeshLambertMaterial({ color: 0x00ff00 }),
  new THREE.MeshPhongMaterial({ color: 0x0000ff, shininess: 80 }),
  new THREE.MeshStandardMaterial({ color: 0xffff00, metalness: 0.8, roughness: 0.2 }),
  new THREE.MeshPhysicalMaterial({ color: 0x00ffff, transmission: 0.9, thickness: 0.5 }),
  new THREE.MeshToonMaterial({ color: 0xff00ff }),
  new THREE.MeshNormalMaterial(),
  new THREE.MeshMatcapMaterial({ matcap: new THREE.TextureLoader().load('matcap.png') })
];

// 逐个摆放材质球
materials.forEach((mat, i) => {
  const mesh = new THREE.Mesh(geometry, mat);
  mesh.position.x = (i - 3.5) * 2;
  mesh.castShadow = true;
  scene.add(mesh);
});

// 粒子系统
const particlesGeo = new THREE.BufferGeometry();
const count = 500;
const positions = new Float32Array(count * 3);
for (let i = 0; i < count * 3; i++) positions[i] = (Math.random() - 0.5) * 10;
particlesGeo.setAttribute('position', new THREE.BufferAttribute(positions, 3));
const particles = new THREE.Points(particlesGeo, new THREE.PointsMaterial({ color: 0xffffff, size: 0.05 }));
scene.add(particles);

// 精灵
const spriteTex = new THREE.TextureLoader().load('https://threejs.org/examples/textures/sprite.png');
const sprite = new THREE.Sprite(new THREE.SpriteMaterial({ map: spriteTex }));
sprite.position.set(0, 3, 0);
scene.add(sprite);

// 渲染循环
function animate() {
  requestAnimationFrame(animate);
  renderer.render(scene, camera);
}
animate();

五、拓展

  1. 性能优化 :移动端尽量避免 PhysicalMaterial,优先 Lambert 或 Matcap。
  2. 项目应用 :建筑可视化用 StandardMaterial,游戏用 ToonMaterial,展示产品用 PhysicalMaterial。
  3. 调试工具 :NormalMaterial 和 DistanceMaterial 特别适合调试几何体和阴影效果。

六、潜在问题

  • 性能瓶颈:PBR 在低端设备上容易掉帧。
  • 阴影丢失 :如果 renderer.shadowMap 没启用,ShadowMaterial 不生效。
  • 光照依赖 :忘记添加光源时,Lambert、Phong、Standard 会显示黑色。
  • 兼容性 :RawShaderMaterial 在不同浏览器可能表现差异。

AI 生成内容声明

本文由人工智能生成,仅供参考与学习,不构成专业建议。

相关推荐
小卿噢14 小时前
同样是插 10 万行,最快的写法比最慢的快 103 倍
前端
weixin_4173968315 小时前
星级酒店境外电视频道怎么合法接入?合规要点与核对清单
开发语言·前端·php·1024程序员节·综合布线
hiahiahia12315 小时前
Structured Output
前端·人工智能
FRing0315 小时前
JavaScript入门到精通三十一(原型继承、原型链)
开发语言·前端·javascript
山雀~16 小时前
CSP 安全漏洞修复
前端·网络协议
陌离17 小时前
Go-Gui:一套 无限接近 现代化UI的 GPU绘制界面组件框架
前端
咚咚咚小柒17 小时前
【前端】LangChain.js学习
前端·javascript·人工智能·typescript·langchain·vue·ai编程
2401_8858850417 小时前
巴林语音通知接口如何对接?系统告警语音API接入教程
android·前端·网络·python·语音识别
java1234_小锋17 小时前
【技术专题】CSS3 网页技术 - CSS3 盒模型
前端·css·css3
计算机魔术师17 小时前
手握芯片、又要吞下开源分发入口,英伟达被盯上了
前端