three.js MeshPhysicalMaterial 详解:基于物理的着色进阶属性、配置参数与实战指南
three.js MeshPhysicalMaterial 详解基于物理的着色进阶属性、配置参数与实战指南【免费下载链接】three.jsJavaScript 3D Library.项目地址: https://gitcode.com/GitHub_Trending/th/three.jsMeshPhysicalMaterial是 three.js 中对 MeshStandardMaterial 的基于物理渲染PBR扩展它在一个统一材质内提供了各向异性Anisotropy、清漆层Clearcoat、虹彩Iridescence、物理传输Transmission、高级反射率、逆反射Retroreflection与织物绒毛光泽Sheen等七大高级能力。本文以 MeshPhysicalMaterial 官方文档 为骨架结合本仓库 src/materials/MeshPhysicalMaterial.js 源码、着色器程序管理与真实示例完整讲解构造方式、每一组属性的取值范围与默认值、贴图通道约定及性能开销并给出可直接运行的车漆、玻璃等材质配置。材质层级与核心定位从源码类声明与文档开头的继承链可以看到Inheritance: EventDispatcher → Material → MeshStandardMaterial → MeshPhysicalMaterialsrc/materials/MeshPhysicalMaterial.js 中类直接extends MeshStandardMaterial这意味着它继承了标准材质全部基础能力color、metalness、roughness、normalMap、envMap等因此可以在场景里无缝替换MeshStandardMaterial使用。它在构造函数中还额外写入了两个编译期宏this.defines { STANDARD: , PHYSICAL: };从 src/materials/MeshPhysicalMaterial.js 可以看到STANDARD与PHYSICAL两个defines常驻开启这正是 shader 中调用扩展版 PBR 光照代码分支的开关。相比普通材质MeshPhysicalMaterial为以下物理现象提供了建模能力Anisotropy各向异性表现拉丝金属一类表面沿特定方向反光差异明显的高光。Clearcoat清漆层车漆、碳纤维、潮湿表面等在粗糙基底层之上还有一层清晰反光薄膜的情形无需额外创建透明面。Iridescence虹彩颜色随观察角与光照角变化如肥皂泡、水面油膜、昆虫翅膀。Physically-based transparency物理透明弥补 Material.opacity 在高度透明时反射不足的问题更真实地表现玻璃这类薄而透明的表面。Advanced reflectivity高级反射率对非金属材质提供更灵活的反射控制。Retroreflection逆反射将镜面高光折返向光源方向用于路标、反光带等安全材料源码注释中列出文档正文的示例列表中亦出现于类注释。Sheen织物绒毛层用于布匹、织物类表面。性能提示原文强调由于上述复杂着色特性MeshPhysicalMaterial的逐像素计算开销高于 three.js 其它材质绝大多数效果默认处于关闭状态开启一个才增加一份开销。想要得到最佳效果使用该材质时务必搭配环境贴图environment map。构造器与参数约定new MeshPhysicalMaterial( parameters : Object )构造一个新的物理材质实例。与所有 three.js 材质一致parameters是包含一个或多个外观属性的对象继承链上的任何属性包括继承自Material、MeshStandardMaterial的属性都能在此传入颜色值可以传任意被Color#set接受的类型如十六进制数、Color实例、CSS 颜色字符串。构造函数末尾统一通过this.setValues( parameters )完成属性赋值见 src/materials/MeshPhysicalMaterial.js。import * as THREE from three; const glass new THREE.MeshPhysicalMaterial( { color: 0xffffff, metalness: 0, // 非金属 roughness: 0.05, transmission: 1, // 全透射模拟玻璃 ior: 1.5, // 折射率 thickness: 0.01, // 体积厚度 specularIntensity: 1, specularColor: 0xffffff, envMap: hdrEquirect, // 物理材质最佳实践必配环境贴图 envMapIntensity: 1 } );分组属性详解数值、默认值与贴图通道约定文档反复出现的 non-color data非颜色数据是一个关键使用规则凡标注为 non-color data 的贴图法线、粗糙度、强度、厚度等其纹理必须保持texture.colorSpace NoColorSpace默认值否则渲染会错误。而标注为 color data 的贴图如sheenColorMap、specularColorMap则应设置texture.colorSpace SRGBColorSpace。各向异性组Anisotropy—— 拉丝金属属性类型/范围默认值含义.anisotropynumber0.0~1.00各向异性强度.anisotropyMapTexturenullR/G 通道存放切向-副切向空间内[-1,1]的方向向量B 通道为[0,1]强度与anisotropy相乘non-color data.anisotropyRotationnumber0在切向-副切向空间中逆时针旋转的弧度存在贴图时叠加额外旋转方向贴图的 R/G 表达的是切向/副切向空间里的向量B 通道只承载强度因此它是典型 non-color data。旋转量以弧度计逆时针为正。清漆层组Clearcoat—— 车漆 / 碳纤维 / 湿表面属性类型/范围默认值含义.clearcoatnumber0.0~1.00清漆层强度开启多层材质基底 薄透光层的入口.clearcoatMapTexturenullR 通道逐像素缩放clearcoatnon-color data.clearcoatRoughnessnumber0.0~1.00清漆层粗糙度.clearcoatRoughnessMapTexturenullG 通道逐像素缩放clearcoatRoughnessnon-color data.clearcoatNormalMapTexturenull为清漆层提供独立法线贴图例如在平整漆面下做划痕细节.clearcoatNormalScaleVector2(0,0)~(1,1)(1,1)clearcoatNormalMap对清漆层的影响强度值得注意的通道约定官方文档与源码均明确clearcoatRoughness读的是贴图 G 通道、clearcoat读的是R 通道、而clearcoatNormalMap是独立的法线贴图。混用通道是这类材质最常见的使用错误。物理传输与体积组Transmission / Volume—— 玻璃与半透明塑料这是MeshPhysicalMaterial区别于标准材质最重量级的一组能力属于 Physically-based transparency属性类型/范围默认值含义.transmissionnumber0.0~1.00透射光学透明程度.transmissionMapTexturenullR 通道逐像素缩放transmissionnon-color data.thicknessnumber0表面下介质的体积厚度以网格自身坐标空间为单位0表示薄壁材质非0表示体积边界.thicknessMapTexturenullG 通道存放厚度值与thickness相乘non-color data.attenuationDistancenumber世界空间单位须 0Infinity介质密度即光在介质中与粒子相互作用前传播的平均距离决定光被吸收的快慢.attenuationColorColor(1,1,1)白光传播到衰减距离后因吸收而呈现的颜色用于模拟彩色玻璃.dispersionnumber≥ 0现实值典型[0,1]0光线穿过相对清澈体积时的色散/色差强度仅对透射物体生效文档特别注明当transmission非零时opacity应设置为1——这是物理模型要求因为全透射的薄塑料/玻璃即便完全透明也保有较强反射用opacity降低透明度反而会削弱反射、破坏物理真实性。transmission的实现代价也是最高的从 WebGLRenderer.js 源码可见WebGL 渲染器会为每个摄像机维护transmissionRenderTarget先把场景背后内容渲染进一个多采样缓冲再做 mipmap 更新与回采且视口需与该缓冲严格对齐。该渲染目标的大小受renderer.transmissionResolutionScale默认为1.0见 WebGLRenderer.js缩放控制实际演示 webgl_materials_physical_transmission.html 把它暴露为可调参数renderer.transmissionResolutionScale params.transmissionResolutionScale; // 0.01 ~ 1可整体缩放透射缓冲分辨率换取性能虹彩组Iridescence—— 肥皂泡 / 油膜 / 昆虫翅膀属性类型/范围默认值含义.iridescencenumber0.0~1.00虹彩层强度模拟随表面-视点夹角变化的 RGB 色相偏移.iridescenceMapTexturenullR 通道逐像素缩放iridescencenon-color data.iridescenceIORnumber1.0~2.3331.3以折射率表征的虹彩 RGB 色移强度.iridescenceThicknessMapTexturenullG 通道存放虹彩层厚度non-color data.iridescenceThicknessRangeArray恰好 2 个元素[100,400]虹彩层厚度最小/最大值区间.iridescenceThicknessMap的映射规则文档明示G 通道0.0→ 厚度等于数组第一个元素G 通道1.0→ 厚度等于数组第二个元素中间值在两个元素间线性插值。虹彩层厚度对色的影响等价于thickness之于ior光程差改变干涉色相因此以纳米级数值为合理量级默认区间[100,400]正是针对可见光波段的经验设定。反射率与镜面反射组Advanced Reflectivity—— 非金属的精细反射控制属性类型/范围默认值含义.iornumber1.0~2.3331.5非金属材质折射率.reflectivitynumber0.0~1.00.5对应 ior 1.5非金属反射程度metalness 1时无效果.specularIntensitynumber0.0~1.01缩放非金属镜面反射量设为0时模型近似 Lambertian.specularIntensityMapTexturenullA 通道逐像素缩放specularIntensitynon-color data.specularColorColor(1,1,1)为法线入射处的镜面反射着色仅非金属.specularColorMapTexturenullRGB 通道逐像素缩放specularColorcolor data应设SRGBColorSpacereflectivity与ior是一对自动换算的镜像属性。查看 src/materials/MeshPhysicalMaterial.js 源码可见其实质是一个Object.defineProperty存取器get: function () { return ( clamp( 2.5 * ( this.ior - 1 ) / ( this.ior 1 ), 0, 1 ) ); }, set: function ( reflectivity ) { this.ior ( 1 0.4 * reflectivity ) / ( 1 - 0.4 * reflectivity ); }即 ior 1.5 时折算 reflectivity 0.5二者指向同一物理量——Fresnel 法线入射反射率——你可以按习惯选用其一引擎负责换算。织物绒毛组Sheen—— 布料与织物属性类型/范围默认值含义.sheennumber0.0~1.00绒毛层强度.sheenColorColor(0,0,0)绒毛着色.sheenColorMapTexturenullRGB 通道逐像素缩放sheenColorcolor data应设SRGBColorSpace.sheenRoughnessnumber0.0~1.01绒毛层粗糙度默认1即默认完全不锐利.sheenRoughnessMapTexturenullA 通道逐像素缩放sheenRoughnessnon-color data织物边缘发白的绒毛反光由sheenColor控制色相、sheenRoughness控制扩散程度是羽绒服、丝绒、地毯等材质建模的基础。注意sheenRoughnessMap走alpha 通道而非 RGB这是它与clearcoatRoughnessMapG 通道不同的读取约定。类型判定与其它成员属性默认值含义.isMeshPhysicalMaterialtrue只读运行时类型探测标志源码在 src/materials/MeshPhysicalMaterial.js 设置this.isMeshPhysicalMaterial true配合单元测试 MeshPhysicalMaterial.tests.js 中 MeshPhysicalMaterial.isMeshPhysicalMaterial should be true 的断言说明它可用于在材质数组中安全过滤物理材质。源码级实现洞察version 自增与着色器分支开关MeshPhysicalMaterial中几个能力开关型属性anisotropy、clearcoat、iridescence、dispersion、retroreflectivity、sheen、transmission在源码里都实现为带副作用的存取器。以anisotropy为例src/materials/MeshPhysicalMaterial.jsget anisotropy() { return this._anisotropy; } set anisotropy( value ) { if ( this._anisotropy 0 ! value 0 ) { this.version ; // 从关闭跨到开启或反之时版本号自增 } this._anisotropy value; }这段实现透露了 three.js 的着色器重编译机制只有当属性从 0 跨过正数边界或在同侧连续调整时才需要让程序缓存失效——从关闭切到开启意味着着色器中新增了对应 feature 的 uniform 与代码路径必须重新编译着色器程序而保持开启时仅微调强度不会触发重编译。着色器程序管理端 WebGLPrograms.js 同样以属性 0 贴图存在的组合推导各宏const HAS_ANISOTROPY material.anisotropy 0; const HAS_CLEARCOAT material.clearcoat 0; const HAS_DISPERSION material.dispersion 0; const HAS_IRIDESCENCE material.iridescence 0; const HAS_SHEEN material.sheen 0; const HAS_TRANSMISSION material.transmission 0; const HAS_TRANSMISSIONMAP HAS_TRANSMISSION !! material.transmissionMap;可见除开clearcoatMap这类贴图宏之外所有开销型特性都以对应数值属性为总闸——数值为 0 时相关贴图与着色分支都不生效这正是文档大多数效果默认关闭、开启才增加成本的底层来源。此外材质还实现了完整的copy()语义src/materials/MeshPhysicalMaterial.jsiridescenceThicknessRange以展开拷贝[ ...source.iridescenceThicknessRange ]避免数组引用共享。实战按真实示例配置典型材质案例一清漆车漆 玻璃webgl_materials_car.html车身漆面是 Clearcoat 的教科书用法——金属漆基底之下叠加一层极光滑清漆const bodyMaterial new THREE.MeshPhysicalMaterial( { color: 0xff0000, metalness: 1.0, // 金属基底 roughness: 0.5, // 基底层中等粗糙提供漫反射着色的金属质感 clearcoat: 1.0, // 开启清漆层 clearcoatRoughness: 0.03 // 清漆层极光滑 → 产生锐利高光与漆面反光 } ); const glassMaterial new THREE.MeshPhysicalMaterial( { color: 0xffffff, metalness: 0, roughness: 0, transmission: 1, // 玻璃车窗物理透射 transparent: true // 可再配合 thickness / ior 控制折射与体积 } );如果要在清漆层上再加划痕等微细法线扰动而不影响基底层法线使用clearcoatNormalMapclearcoatNormalScale即可让两层拥有各自独立的法线。案例二可交互玻璃参数面板webgl_materials_physical_transmission.html该示例把透射类参数完整暴露到 lil-gui是调试玻璃材质的最佳起点。核心材质初始化与 GUI 回写逻辑为const material new THREE.MeshPhysicalMaterial( { color: 0xffffff, metalness: 0, roughness: 0, transmission: params.transmission, // 建议为 1玻璃 ior: params.ior, // 1 ~ 2默认 1.5 thickness: params.thickness, // 0 ~ 5 specularIntensity: params.specularIntensity, specularColor: params.specularColor, envMap: hdrEquirect, // 环境贴图驱动透射/反射采样 envMapIntensity: params.envMapIntensity } ); gui.add( params, transmission, 0, 1, 0.01 ).onChange( () material.transmission params.transmission ); gui.add( params, ior, 1, 2, 0.01 ).onChange( () material.ior params.ior ); gui.add( params, thickness, 0, 5, 0.01 ).onChange( () material.thickness params.thickness ); gui.addColor( params, specularColor ).onChange( () material.specularColor.set( params.specularColor ) ); gui.add( params, transmissionResolutionScale, 0.01, 1, 0.01 ) .name( transmission resolution ) .onChange( () renderer.transmissionResolutionScale params.transmissionResolutionScale );示例同样把renderer.toneMapping ACESFilmicToneMapping与环境贴图作为渲染前提印证了物理材质 环境贴图 色调映射的组合惯例。同目录下还提供了透明度混合进阶版 webgl_materials_physical_transmission_alpha.html 与 WebGPU 版本 webgpu_materials_transmission.html可用浏览器直接打开查看不同渲染后端下的效果差异。案例三各向异性 / 虹彩 / 逆反射的轻量组合对开启强度类效果推荐直接使用材质自带的数值总闸 存取器副作用机制——在动画循环中连续修改即可无需触碰 uniform// 拉丝金属Brush metal基础配方 const brushed new THREE.MeshPhysicalMaterial( { metalness: 1.0, roughness: 0.3, anisotropy: 0.5, // 拉丝高光 anisotropyRotation: Math.PI / 2 // 以弧度逆时针旋转拉丝方向 } ); // 手表表盘一类带虹彩的镜面示例 webgl_watch.html 中使用 iridescence: 0.3 const dial new THREE.MeshPhysicalMaterial( { metalness: 1.0, roughness: 0.1, iridescence: 0.3, iridescenceIOR: 1.3 } ); // 反光带/安全材料示例 webgpu_materials_retroreflection.html 中 retroreflectivity: 1.0 const tape new THREE.MeshPhysicalMaterial( { color: 0xcccccc, metalness: 0, roughness: 0.5, retroreflectivity: 1.0 } );anisotropyRotation的默认值以本仓库源码 src/materials/MeshPhysicalMaterial.js 的this.anisotropyRotation 0为准弧度制逆时针为正从切向量起算。上述配方对应的完整演示还可在 material-browser 场景面板中对照查看。使用要点清单环境贴图几乎必需透射折射、清漆反射与金属反射都依赖环境采样文档明确建议always specify an environment map。colorSpace 双轨制非颜色数据贴图强度/粗糙/法线/厚度等保持NoColorSpace颜色数据贴图sheenColorMap、specularColorMap设为SRGBColorSpace。transmission 与 opacity 二选一transmission 0时应让opacity 1把透明度交给物理透射路径处理。按需开启特性每开启一项高级效果transmission 尤甚都会引入额外着色分支乃至额外渲染 pass只开启视觉所需的最小集合。共享 MeshStandardMaterial 生态其全部基础属性、defines机制、copy()、类型判定标志以及 MeshPhysicalMaterial.tests.js 覆盖的单元测试均可直接沿用迁移成本极低。ior / reflectivity 可互换两者由存取器自动换算同一材质内只需维护其中一个避免对非金属反射率做双重调参。相关资源类定义源码src/materials/MeshPhysicalMaterial.js基类src/materials/MeshStandardMaterial.js单元测试test/unit/src/materials/MeshPhysicalMaterial.tests.js着色器特性宏判定src/renderers/webgl/WebGLPrograms.js透射渲染缓冲实现src/renderers/WebGLRenderer.js可运行示例webgl_materials_car.html、webgl_materials_physical_transmission.html、webgl_materials_physical_transmission_alpha.html、webgl_materials_envmaps_fasthdr.html、webgpu_materials_transmission.html交互材质浏览器docs/scenes/material-browser.html【免费下载链接】three.jsJavaScript 3D Library.项目地址: https://gitcode.com/GitHub_Trending/th/three.js创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考