一、材质核心概念
Three.js中的Material定义了3D物体表面的视觉特性,控制光线与物体表面的交互方式。作为几何体的"皮肤",材质通过颜色、纹理、金属度等属性实现真实感渲染。所有材质继承自基类THREE.Material,包含color、opacity、side等通用属性。
二、材质分类与特性对比
1、 基础材质
| 材质类型 | 光照支持 | 性能消耗 | 典型应用场景 |
|---|---|---|---|
| MeshBasicMaterial | 否 | 最低 | UI元素/线框模型 |
| PointsMaterial | 否 | 低 | 粒子系统 |
| LineBasicMaterial | 否 | 低 | 路径绘制 |
示例代码:
// 红色半透明立方体
const material = new THREE.MeshBasicMaterial({
color: 0xff0000,
transparent: true,
opacity: 0.5,
wireframe: true
});
2、光照敏感材质
| 材质类型 | 反射模型 | 特性 |
|---|---|---|
| MeshLambertMaterial | Lambert | 漫反射,无高光 |
| MeshPhongMaterial | Blinn-Phong | 支持镜面高光 |
| MeshStandardMaterial | PBR | 金属度/粗糙度控制 |
物理渲染(PBR)参数:
metalness:金属质感强度(0-1)roughness:表面粗糙度(0-1)envMap:环境贴图
3、 特殊用途材质
| 材质类型 | 功能特性 |
|---|---|
| ShadowMaterial | 仅接收阴影 |
| MeshDepthMaterial | 深度可视化(近白远黑) |
| MeshNormalMaterial | 法线方向可视化(RGB映射) |
三、关键属性配置
1、颜色与透明度
// HSL颜色设置
material.color.setHSL(0.5, 1, 0.5);
// 透明度配置
material.transparent = true;
material.opacity = 0.7;
2、纹理映射
| 贴图类型 | 作用描述 | 代码示例 |
|---|---|---|
| map | 基础颜色纹理 | map: textureLoader.load() |
| normalMap | 法线贴图(表面凹凸) | normalScale: new Vector2(1,1) |
| displacementMap | 位移贴图(几何形变) | displacementScale: 0.1 |
3、高级光照属性
// Phong材质高光配置
const phongMat = new THREE.MeshPhongMaterial({
specular: 0xffffff, // 高光颜色
shininess: 100 // 光泽度(0-100)
});
// 自发光设置
material.emissive.set(0xff0000);
material.emissiveIntensity = 1.5;
四、自定义材质开发
1、ShaderMaterial
通过GLSL编写自定义着色器:
// 顶点着色器
varying vec3 vPosition;
void main() {
vPosition = position;
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}
// 片元着色器
uniform vec3 color;
varying vec3 vPosition;
void main() {
gl_FragColor = vec4(color * vPosition.z, 1.0);
}
2、材质动画
function animate() {
requestAnimationFrame(animate);
material.uniforms.time.value += 0.01;
renderer.render(scene, camera);
}
五、性能优化策略
- 材质复用:相同材质的网格共享Material实例
- 纹理压缩:使用
.basis或.ktx2格式纹理 - LOD控制:根据距离切换材质精度
- 属性冻结:
material.needsUpdate = false; // 停止材质更新
六、调试技巧
1、 法线可视化:
const helper = new THREE.FaceNormalsHelper(mesh, 2);
scene.add(helper);
2、性能监控
import Stats from 'stats.js';
const stats = new Stats();
stats.showPanel(0);
document.body.appendChild(stats.dom);
更多three.js、cesium.js开源案例,请移至gitee.com/giser2017/t…