3.1 材质谱系:从基础漆到 PBR 车漆 本节摘要:材质回答的是"光打上去之后发生什么"。本节把常用材质按反光模型排成一条谱系线:Basic 不吃光、Lambert 只算漫反射、Phong 加高光、Standard 走物理流程、Physical 补清漆与透光。承接第 2 章的灯光,本节让货箱第一次"对光有反应",并给出选材决策面板。 素坯与成品漆之间隔着几层 第 1 章首件样板用的 MeshBasicMaterial 是"素坯漆":颜色直接画上去,不问光照。布光工位之所以能开工,是因为我们换了 MeshStandardMaterial——从这一刻起,材质开始向灯光"询价":这盏灯照到我多少、环境里有什么可反射的、我表面粗糙到什么程度。
本节摘要:材质回答的是"光打上去之后发生什么"。本节把常用材质按反光模型排成一条谱系线:Basic 不吃光、Lambert 只算漫反射、Phong 加高光、Standard 走物理流程、Physical 补清漆与透光。承接第 2 章的灯光,本节让货箱第一次"对光有反应",并给出选材决策面板。
第 1 章首件样板用的 MeshBasicMaterial 是"素坯漆":颜色直接画上去,不问光照。布光工位之所以能开工,是因为我们换了 MeshStandardMaterial——从这一刻起,材质开始向灯光"询价":这盏灯照到我多少、环境里有什么可反射的、我表面粗糙到什么程度。材质谱系的本质,就是"向光照模型询价的深度"不同:问得越细,表现越真实,着色开销也越大。谱系线上的每一个档位都有存在理由,"直接上最贵的"是新手最常见的选择错误。

MeshBasicMaterial 不参与光照,颜色即所见。它的岗位不止"入门":UI 面板色块、自发光的仪表指针、不受任何灯光影响的发光标牌,都是它的正业——这些物件"本来就不该有明暗"。Lambert 只计算漫反射,光从面来、按角度衰减,没有高光;它便宜且哑光,适合布料、水泥、瓦片这类"不给反光戏份"的表面,低端机型的性能兜底也常落在它身上。
Phong 在漫反射之外加了一瓣可调高光(shininess 控大小、specular 控强度),塑料壳、瓷碗、抛光桌面这些"有一小块亮斑"的材质,用 Phong 比上 Standard 更划算。MeshStandardMaterial 是本谱系的主力:roughness 与 metalness 两颗旋钮走物理渲染(PBR)流程,配合纹理与环境贴图能覆盖九成实物表现。MeshPhysicalMaterial 在 Standard 之上追加清漆层(clearcoat,车漆与钢琴漆)、透光(transmission,玻璃毛球)、彩虹镀膜(iridescence,肥皂泡光盘)——每个特性都是真实的着色成本,不用不占,要用就明确是为这一层效果付账。
背景:沙盘货箱统一灰色过于呆板。客户指定三种皮:普通纸箱(哑光吸光)、周转塑料箱(半亮反光)、金属扣件(镜面金属),并且低配设备不能掉帧。
操作:三种皮分别落到谱系的三档——Lambert、Standard、Standard 加环境贴图,一个材质一个岗位。
// 1. 纸箱:哑光吸光,Lambert 足够,便宜 const paperMat = new THREE.MeshLambertMaterial({ color: 0xc9a86a }); // 2. 塑料箱:Standard,roughness 压出塑料感 const plasticMat = new THREE.MeshStandardMaterial({ color: 0x3a6ea5, roughness: 0.35, // 偏亮的小反光面,塑料味的主要来源 metalness: 0.0 // 塑料是绝缘体,金属度保持 0 }); // 3. 金属扣件:Standard 高金属度,必须配环境贴图 const envMap = stage.scene.environment; // 假设已用环境贴图工具配置(见本节末尾) const metalMat = new THREE.MeshStandardMaterial({ color: 0xb8bcc0, roughness: 0.18, metalness: 1.0, envMap, envMapIntensity: 1.2 // 反射强度微调,过强会像镀铬玩具 });
结果:三只箱子并排摆在灯光下——纸箱只有明暗没有反光,塑料箱侧面拖出一小瓣高光,金属件把周围的灯光与环境映在身上。三档材质的着色开销梯度清晰:低配设备把塑料箱与金属件临时换回 Lambert,帧率立刻回升,视觉损失可接受。
解读:金属件那三行注释是本节的真正考点。metalness 等于 1 的材质几乎不显示基色,它显示的是"环境"——没有环境贴图时无处可反,画面上就是一团黑。环境贴图从哪来?最省事的路径是用官方的环境贴图工具加载一张全景图并挂到 scene.environment,场景内所有 Standard 与 Physical 材质自动获得反射源,一行配置全场景受益。这也解释了为什么"金属发黑"永远是排障榜前三:灯只照亮,不提供反射。
变式:把塑料箱的 roughness 换成一张灰度噪声贴图(白色粗糙、黑色光滑),表面出现"有的地方反光有的地方磨砂"的磨损感——这就是 3.3 节粗糙度贴图的预告。再试 Physical:给塑料箱加 clearcoat 等于 1,塑料瞬间升级成"浸过清漆的工艺品",顺便在控制台看看帧率付了多少账。
谱系之外还有两个高频特殊岗位要提前登记。透明件(玻璃罩、水面、半透磨砂)用 transparent 加 opacity 控制,但透明物不写深度缓冲时会与背景排序错乱——玻璃罩里套物件出现"前后穿帮",处置是分清透明物的层级,必要时用 renderOrder 手工定序,或改用 Physical 的 transmission 做真折射(贵但正确)。双面件(薄布、打开的盒盖、地面上的镂空格栅)默认只渲染正面,从背面看直接消失;side 属性设为双面即可,代价是绘制面数翻倍——大面积地面没必要双面,小薄片才是它的岗位。这两处配置各只占一行,但翻车率极高,原因都是"默认值服务的是最常见的实体不透明件"。
漆已选定,下一节备料:贴图文件进显存前要过的色彩空间与米普链两道关卡——很多"怎么调都脏"的材质,病根在这节。