材质决定“怎么算颜色”
几何体决定形状,材质决定每个像素的颜色怎么计算。three.js 会把材质编译成一对着色器(GLSL 程序)。不同材质的区别,本质上是光照公式不同、计算量不同。
从便宜到昂贵
- MeshBasicMaterial:不受光照影响,只输出颜色或贴图。适合 UI、发光体、调试。
- MeshLambertMaterial:只有漫反射(哑光),没有高光。计算便宜,适合大面积的粗糙表面。
- MeshPhongMaterial:漫反射 + 镜面高光,用
shininess控制高光的锐利程度。经典但不“物理”。 - MeshStandardMaterial:基于物理的渲染(PBR),用
roughness(粗糙度)和metalness(金属度)两个直观参数描述表面,在任何光照下都更可信。 - MeshPhysicalMaterial:Standard 的扩展,额外支持清漆层
clearcoat、光泽sheen、透射、虹彩等,效果最好也最贵。
还有两个风格化/调试材质:
- MeshToonMaterial:卡通渲染,用一张很小的
gradientMap把连续的明暗切成几条色带。示例用 3 个像素的DataTexture,并设置NearestFilter防止色带被插值模糊。 - MeshNormalMaterial:把法线方向直接映射成 RGB,不需要灯光,常用来检查法线是否正确。
为什么金属需要环境贴图
金属几乎没有漫反射,它的颜色来自反射周围环境。如果场景里只有几盏点光源,把 metalness 拉到 1 会看到物体几乎全黑。示例给场景设置了 scene.environment(由 RoomEnvironment 生成),只有 Standard / Physical 会自动使用它,所以调高 metalness 时它们依然好看。
修改材质的小规则
大多数数值(颜色、roughness、shininess)改了立即生效;但会改变着色器代码的属性,比如 flatShading,需要设置 material.needsUpdate = true 让 three.js 重新编译。
拖动 metalness 和 roughness,观察 Standard 与 Physical 的变化,而 Lambert、Phong 完全不受影响。
核心 API
THREE.MeshBasicMaterialTHREE.MeshLambertMaterialTHREE.MeshPhongMaterialTHREE.MeshStandardMaterialTHREE.MeshPhysicalMaterialTHREE.MeshToonMaterialTHREE.MeshNormalMaterialmaterial.needsUpdatescene.environment动手试试
- 1把 envIntensity 调到 0,再把 metalness 拉到 1,看看 Standard 和 Physical 为什么变黑。
- 2给 toonRamp 增加到 5 个灰度级,让卡通色带更细。
- 3把 Physical 的 clearcoat 设为 1、roughness 设为 0.8,做出“磨砂底 + 亮面漆”的效果。
- 4给 Phong 材质设置 emissive: "#330022",观察自发光如何叠加在光照之上。
还没有输出。console.log 的内容会显示在这里。
运行中