经纬志
首页 / three.js / API 文档

Material

先看结论

所有材质的基类,定义表面的通用渲染行为:透明度、面朝向、深度测试、混合方式与着色器行为。

最后验证 2026-11-03 · three.js 0.160.0 · 更新 2026-10-27 · 引用本文
new THREE.Material(parameters) → Material

基类通用属性

属性默认说明
opacity1不透明度,需要同时把 transparent 设为 true 才生效
transparentfalse开启透明混合,会引入排序问题与额外开销
alphaTest0低于该 alpha 的片元直接丢弃,适合植被、栏杆等镂空贴图
sideFrontSide正面、背面或双面渲染,双面会翻倍片元开销
depthTesttrue是否参与深度比较
depthWritetrue是否写入深度缓冲,透明物体常设为 false
colorWritetrue是否写入颜色,可做只写深度的预处理
blendingNormalBlending混合模式,发光效果常用 AdditiveBlending
polygonOffsetfalse多边形偏移,用于压住共面闪烁(如贴地标线)
toneMappedtrue是否参与色调映射,UI 类元素可关闭以保持纯色
fogtrue是否受场景雾影响
needsUpdate—置 true 触发着色器重编译,见下文

常用材质与关键参数

材质关键参数适用
MeshBasicMaterialcolor、map不受光,标注、辅助线、背景
MeshLambertMaterialcolor、emissive漫反射,大范围地形
MeshStandardMaterialroughness、metalness、map、normalMapPBR 默认选择
MeshPhysicalMaterialclearcoat、transmission、ior、thickness玻璃、水面、车漆
LineBasicMaterialcolor、linewidth轨迹、经纬网、边框
PointsMaterialsize、map、vertexColors点云、粒子
SpriteMaterialmap、depthTest始终朝向相机的标签

linewidth 在绝大多数平台上固定为 1,WebGL 并不保证支持更宽的线。 需要粗线时要用 Line2 或把线做成管状几何体。

创建与修改

const material = new THREE.MeshStandardMaterial({
  color: 0x4f9ef8,
  roughness: 0.45,
  metalness: 0.12,
  transparent: true,
  opacity: 0.9,
  side: THREE.DoubleSide,
  polygonOffset: true,
  polygonOffsetFactor: -1,
  polygonOffsetUnits: -1
});

// 改颜色、透明度:不需要重编译
material.color.setHex(0xff8844);
material.opacity = 0.6;

// 增删贴图、切换 vertexColors:需要重编译
material.map = newTexture;
material.needsUpdate = true;

什么时候需要 needsUpdate

材质的着色器是按「启用了哪些特性」编译的。改变数值(颜色、粗糙度、透明度)不会改变着色器结构, 直接赋值即可生效。改变结构(新增贴图、移除贴图、开关顶点颜色、切换是否受雾影响) 会改变着色器代码,必须置 needsUpdate = true,下一次渲染时重新编译。

重编译会造成一帧卡顿。批量场景里逐个切换材质结构,最好一次性完成, 避免在动画过程中零散触发。

透明与排序

透明物体默认按到相机的距离从远到近排序,但排序以对象中心为单位,不是逐片元。 相互穿插的透明面片、贴地的半透明图层,经常出现前后关系错误。 常见处理是:透明面片关闭 depthWrite,叠加图层用 AdditiveBlending,并手动控制 renderOrder。

大面积半透明面(如云层、热力面)如果看得出明显的三角形接缝, 多半是深度写入与混合顺序导致,而不是着色器有错。

贴图与色彩空间

颜色贴图(map、emissiveMap)应标为 sRGB; 数据贴图(normalMap、roughnessMap、metalnessMap) 保持线性。标错会让光照方向或表面粗糙度整体偏移。

释放

material.dispose() 释放材质关联的着色器程序。材质里的贴图要单独调用 texture.dispose()。两者都不在网格移除时自动触发。

同一材质才能合批。大量外观相同的小物件共享一份材质,渲染器的状态切换最少。 如果每个对象都要独立颜色,优先考虑顶点色或 InstancedMesh 的实例颜色, 而不是逐个克隆材质。

引用本文

经纬志(2026)。《Material》。https://www.jingweizhi.com/three/api/material.html(访问日期 2026-11-03)。