1. 两条高光背后的物理模型:aistandardhair的设计逻辑
做角色项目的人基本都有过这种经历:模型精度不低,贴图画得也不差,灯光一打上去,头发怎么看怎么不对劲,要么像戴了一顶塑料假发,要么像涂了发胶的钢丝球。我早期用Blinn或者Phong硬调头发材质,把Eccentricity拉到特定值,再叠一层斜坡渐变贴图模拟发丝明暗,折腾半天,渲染出来还是被甲方一句话打回:“头发太假了。”后来换到Arnold渲染器,才真正意识到问题不在灯光也不在模型,而在于常规的材质模型压根不是为“纤维”设计的。
aistandardhair这个材质节点,表面看是Arnold提供给Maya的一键式头发Shader,但它的底层逻辑和Blinn完全是两套思路。Blinn模拟的是一个“光滑曲面”的反射,所以它只有一条高光,高光的位置和形状由法线决定。而真实的一根发丝是半透明的圆柱纤维,光线打上去之后会走三条完全不同的路径:一部分光在纤维表面直接反射,这部分叫R,形成主高光,颜色偏白,位置靠近光源方向;另一部分光折射进入发丝内部,被皮质层里的黑色素吸收一部分之后再穿出来,这部分叫TT,它是头发的透射光,也是发色看起来有厚度的核心;第三部分光进入发丝后在背面发生一次内反射再穿出,叫TRT,它会在主高光旁边偏移出一个次级高光,位置略偏、颜色明显带发色。这就是为什么真实头发的高光永远是两条,一条硬一条软、一条偏白一条偏色。
如果你用Blinn去模拟这种效果,你只能做到“加两个高光节点叠在一起”,但两条高光的亮度比例、偏移程度、颜色关系又完全取决于入射角和纤维的折射率,手动去K等于在做梦。aistandardhair把这三条光路全部内置,你只需要调几个参数,就能复现从黑直发到浅金大波浪的绝大部分真实发质变化。Arnold从5.0开始用aistandardhair替代了老的standard hair shader,在Maya里创建的方式也很直接:渲染菜单栏里Arnold > Shader > Aistandardhair,或者直接在Hypershade里建一个aiStandardHair节点,材质球图标是一个带曲线段的圆筒示意,一眼就能认出。
我在不少项目里见过有人建了这个节点之后,只在Color里随便点了个棕色就丢上去渲染,结果出来的头发又黑又闷,然后回头吐槽Arnold的头发材质不好用。其实不是材质不好用,而是你没有理解这个Shader默认状态下为什么这么“保守”。aistandardhair的默认参数更接近深色直发,所有光路的权重都是偏低的,你需要主动调整Transmission、Secondary Specular这些项才能解锁不同发质。所以这篇文章我打算从光路模型开始,带你把参数面板上的每个滑块都过一遍,再给几组可以直接抄作业的配色配方,最后聊一聊渲染端和Maya 2022环境里那些容易让人白调一晚的坑。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 从Color到Transmission:把aistandardhair参数翻译成人话
打开aistandardhair的属性编辑器,第一眼看到的分组有Base、Specular、Transmission、Coat、Fuzz、Opacity这些,相比Blinn来说参数不算多,但每个都有明确的物理对应。我把它们按实际调参的优先级重新排个序讲。
2.1 决定“发色”的三个开关:Base Color、Melanin和Dye Color
Color这一组是头发的底色来源,里面有三个层级:Base Color、Melanin、Dye Color。很多新手一上来就改Base Color,改了半天发现颜色并不对——因为真正决定最终发色的是三者叠加的结果。
先说Melanin,黑色素。这是真实头发颜色深浅的核心参数,取值范围0到1,值越高头发越深。亚洲人黑发的Melanin基本在0.85到1.0之间,浅金发在0.2到0.4之间,白发则直接拉到0。Melanin旁边还有一个Melanin Color,默认是偏红棕的,这个颜色决定了黑色素的“色相偏移”。同样是Melanin 0.6,如果你把Melanin Color偏向红棕,头发出来就是深栗色;偏向金黄,头发就是深亚麻色。我在调色时的习惯是,先把Base Color设成一个比目标发色稍浅一点的中性色,然后通过Melanin和Melanin Color把明度和色调压到想要的位置。这样比直接在Base Color里硬点颜色更接近真实头发的“半透明染色”效果。
Dye Color则是染发剂的颜色逻辑。它不同于Base Color的地方在于,它更像是在黑色素基础上叠加了一层“染色滤镜”。举个例子,你做一个深棕底色但是发梢漂染成灰蓝色的角色,正确做法是保留Melanin在0.7左右,然后给Dye Color一个低饱和的蓝灰色,Dye Color不会把头发完全变成蓝色,而是让光线在穿过发丝时带上一点蓝灰色调,效果会比直接铺一张带颜色的贴图自然得多。所以Dye Color特别适合做挑染、渐变染和奇幻发色。
除此之外还有个容易被忽略的参数叫Opacity,默认是1,也就是完全不透明。做正常的头发不用动它,但如果你想做眉毛、睫毛、脸上的绒毛、或者近景里的碎发,把Opacity降到0.5以下,配合较低的Specular和较高的Transmission,能做出那种边缘有一些半透明飘散感的效果,比直接用Opacity 1的实体曲线看着柔软得多。
2.2 主高光与次级高光:两个Specular和两个Roughness
Specular这一组是aistandardhair的核心区域,也是和真实头发光路模型对应最紧密的地方。它把高光拆成了两层:Specular对应主高光R,Secondary Specular对应次级高光TRT。
Specular控制主高光的强度,一般取0.8到1.2;Secondary Specular控制次级高光的强度,取0.4到1.0。要注意的是,次级高光的默认强度往往偏弱,很多经验不足的人调完头发觉得“还是不够有光泽”,第一反应是提高Specular,结果主高光变成一道刺眼的白色光带,发丝质感全没了。正确做法是提高Secondary Specular,次级高光才是给头发带来“发质顺滑感”的那条光带,它位置偏、颜色带发色,让人觉得头发是被光“穿透”而不是被光“弹开”。
两个Roughness分别控制主高光和次级高光的锐利程度。主高光的Roughness我一般设在0.25到0.4之间,太低会显得头发像涂了油;次级高光的Roughness在0.35到0.6之间,比主高光略高一点,这样两条高光有层次。真实头发的主高光通常比次级高光更尖锐,因为R路径发生在光滑的毛鳞片表面,而TRT路径在内部经过了更复杂的散射。
这里要提一下Specular Model,默认是GGX。做写实头发就保持GGX不动,做偏卡通或风格化角色时可以切到Beckmann,高光会收得更圆润一些。另外,Secondary Specular Color这个参数很多人不知道是用来干嘛的:默认是白色,它的作用是给次级高光做颜色修正。在做冷色调灯光场景时,我常常把Secondary Specular Color稍微压暗一点点,避免次级高光太跳。
2.3 Transmission:头发的“透光”是灵魂
Transmission是aistandardhair里最容易被低估的参数。它的字面意思是透射强度,控制光线穿透头发的比例。当Transmission为0的时候,头发就是一个不透明的圆柱体,光线全部在表面反射或散射,你会发现头发就算加了Secondary高光,整体还是很“实”、很“闷”。把Transmission拉到0.6以上,光开始能穿透发丝了,发色会变得通透,发缝和发际线处能看到皮肤透上来的光晕,这种“透”的感觉就是真实头发区别于塑料假发最关键的一环。
但透射不是越大越好。Transmission拉太高,头发会像玻璃丝一样发亮,尤其在做深色头发时,高透射会让发色变浅得很奇怪。所以Transmission要跟Transmission Depth配合用。Transmission Depth的意思是光线在纤维里走多深就会被完全吸收,单位是厘米左右。深色头发里黑色素多,吸收强,Depth可以设小一点(0.2到0.5);浅色头发吸收弱,光线能走得更深,Depth设到1.0到2.0,发色会更有“由内而外”的柔和感。
我自己的经验是:先定发色,再定透射,最后返回来微调Base Color。因为加了透射之后,头发的整体颜色会变浅、变柔和,如果你在透射为0时就调好了Base Color,一开透射颜色马上不对。所以我做写实头发的调参顺序是:Melanin和Base Color定大方向 → Transmission和Depth调到理想通透度 → 回到Base Color微调明度 → 再去动Specular。
2.4 Coat、Fuzz和Angle:顺滑度、绒毛感与高光方向
Coat是头发表面的覆盖层强度,对应现实中头发最外层的毛鳞片和护发精油那层油膜。Coat强度越高,头发越“顺滑”,高光越聚集,但也会让头发看起来油。我平时做女性角色顺滑长发的Coat在0.5到0.7之间,做男性短发或者偏毛躁的自然卷,Coat就降到0.2到0.3,配合稍高的Roughness,头发看起来更蓬松。
Fuzz是绒毛层,专门控制光线在发丝边缘产生的细小散射,对发际线和碎发特别关键。做写实角色时Fuzz开到0.3到0.5就够了,Fuzz越大头发越像有一层细毛包裹着。做卡通角色或者毛发蓬松的小动物时,Fuzz可以拉到0.8以上,会得到一种类似柔光边缘的效果。
Angle这个参数控制高光绕着发丝轴旋转的角度,默认0是正常状态。它出问题的典型场景是导入的外部曲线模型:同样一个材质赋到两组发丝曲线组上,一组高光正常一组高光斜掉,八成就是曲线本身的UV方向不一致。在Arnold Hair中,头发的方向沿曲线切线计算,但高光偏转是依赖曲线在UV空间里的走向,如果你的发丝曲线是从其他软件导入的,它的方向属性可能没对齐,这时候用Angle修正比重新梳理曲线快得多。
3. 黑发、金发、白发、红发:四组可以直接抄的调参配方
理论讲再多,不如直接给参数。下面这几组配方是我在多个写实项目中实际用过的基准值,不一定每个场景都完全适用,但作为起点非常靠谱。
3.1 亚洲深色直发配方
Base Color用深棕偏一点暖红,RGB大概在(0.16, 0.10, 0.08),Melanin给0.9以上,Melanin Color保持默认的棕红。Specular为0.9,Roughness约0.3;Secondary Specular给0.5,Roughness约0.45。Transmission给0.4,Depth设为0.3。Coat给0.5,Fuzz给0.35。
这套参数最需要注意的是Transmission不能给太高,0.4在写实场景下刚刚好。亚洲人的黑发在逆光下的确会透光,但透出来的颜色是偏绛红偏暖的,而不是单纯的变浅。所以Depth保持较小,让光在发丝内部稍微走一下就吸收掉,出来的效果会非常实。灯光方面,深色头发需要明显的轮廓光才能拉开层次,建议主光用柔光箱,背后加一条边缘硬一点的冷色轮廓光,头发的两条高光一下子就能出来。
3.2 欧美浅金发配方
Base Color给(0.55, 0.42, 0.25),Melanin降到0.3,Melanin Color改成偏金黄,RGB约(1.0, 0.75, 0.3)。Specular给1.0,Roughness约0.35;Secondary Specular给0.8,Roughness约0.4。Transmission给0.7,Depth必须增大到1.5左右。Coat给0.4,Fuzz给0.4。
金发是透射效果最明显的发色,因为黑色素少、光线穿透能力强。如果你在浅金发上继续沿用深色头发的Depth 0.3,头发会变成一种没有厚度的亮黄色塑料片。Depth上到1.5之后,光在发丝内部走得更远,二次散射增多,发色会呈现一种从内部泛出来的柔和浅金色。另外金发的次级高光非常明显,如果觉得不够,可以先加Secondary Specular而不是动主高光。
3.3 银发/白发配方
Base Color给(0.75, 0.72, 0.68),Melanin直接给0,Melanin Color无所谓因为采样率已经是零了。Specular给1.1,Roughness约0.3;Secondary Specular给0.9,Roughness约0.35。Transmission给0.8,Depth给2.0。Coat给0.3,Fuzz给0.5。
白发处理时最忌讳的是把Base Color调成惨白色。真实的银发在环境光中会带上冷灰、浅蓝、淡紫的环境色,所以Base Color要带一点灰度和冷暖倾向,纯白反而最不像白发。另外白色头发的次级高光偏强、主高光也偏硬,因为浅色纤维内部的吸收少,TRT路径的能量损失很低。如果要做年长角色的花白发,可以把一张低频噪波贴图连到Melanin上,让0到1之间的黑色素随机分布,效果比在Base Color上画花白要自然非常多。
3.4 红发和风格化发色
红发的难点在于它的色调非常挑剔。我发现直接用Dye Color来做红发比调Melanin Color更稳定:Base Color给深红棕(0.2, 0.08, 0.05),Melanin给0.7,Dye Color给一个明亮的橙红色(0.85, 0.2, 0.05)。这样相当于在深色底色上叠加了一层明亮的染发层,出来的红色既有厚度又有光泽。Transmission给0.6,Depth给1.0,光穿透时的颜色修正会由Dye Color自动完成。红发的次级高光会非常漂亮,Secondary Specular可以给到0.9。
如果是二次元或者风格化角色,不用纠结物理准确性。我一般会把Specular开到1.2以上、Roughness降到0.15,做出那种糖果纸一样的高光;Fuzz拉到0.9,让整颗头看起来毛茸茸的;Melanin给0.3左右然后在Dye Color里直接选一个高饱和的梦幻色。不要开太高Transmission,风格化头发保持一定的“实心感”反而更有插画味道。
下面这张表可以直接存下来当速查:
| 发色 | Base Color | Melanin | Specular | Sec Specular | Roughness | Transmission | Depth |
|---|---|---|---|---|---|---|---|
| 亚洲黑直发 | 0.16, 0.10, 0.08 | 0.9-1.0 | 0.9 | 0.5 | 0.3 | 0.4 | 0.3 |
| 深棕 | 0.3, 0.18, 0.12 | 0.7 | 0.95 | 0.55 | 0.32 | 0.5 | 0.6 |
| 浅金 | 0.55, 0.42, 0.25 | 0.3 | 1.0 | 0.8 | 0.35 | 0.7 | 1.5 |
| 银白 | 0.75, 0.72, 0.68 | 0 | 1.1 | 0.9 | 0.3 | 0.8 | 2.0 |
| 红发 | 0.2, 0.08, 0.05 | 0.7 | 0.95 | 0.9 | 0.3 | 0.6 | 1.0 |
4. 曲线、采样与AOV:渲染端比材质端更容易翻车的地方
材质参数调完了,不代表渲染就万事大吉。毛发渲染的特殊性在于,它是纯几何曲线数据,跟普通多边形面片在渲染管线里的走向完全不同。很多人在Maya里调了半天材质,渲染出来还是不对,问题往往出在渲染设置和AOV上。
4.1 先检查曲线宽度和方向:材质再好也救不了反了的曲线
这是我在项目中踩过最深的坑之一。做头发模型时通常会用Maya的nHair、XGen转Curves、或者从外部导入引导线来生成最终渲染用的曲线。这些曲线的宽度由两个地方控制:曲线自身的Width通道和Arnold的Curve Width Scale。如果所有发丝渲染出来细得像蜘蛛丝,多半是曲线上没有给Width值,或者给了但被Scale缩小了。一个常用的做法是,用每根曲线最近邻的发根到发梢距离做比例换算,给曲线的Width一个渐变值:发根宽一点、发梢收细。在Maya里可以在Curve的Shape节点上给Width一个Ramp贴图,或者在XGen的导出阶段就做好宽度烘焙。
另一个更隐蔽的问题是曲线的方向。Arnold在渲染曲线时,颜色贴图的V方向沿着曲线长度方向,U方向沿着曲线横截面方向。如果你的模型是从别的软件导进来的OBJ曲线,或者You在Maya里用“Reverse Direction”反转过曲线方向,那么aistandardhair的Angle高光方向会跟着变。典型表现是:同一套材质赋给两撮头发,一撮高光在正确位置,另一撮高光整体偏了90度甚至翻转。解决办法是选中那撮头发曲线,用Modeling Toolkit里的Curve > Reverse Direction把曲线方向反过来,或者直接用材质上的Angle手动补偿。我建议优先改曲线方向,而不是依赖材质里的Angle,因为曲线方向还会影响贴图的U/V分布,不纠正的话后面做渐变发色一样会出问题。
4.2 毛发的抗锯齿采样:噪点不是提高AA Samples就能解决的
毛发的几何本体非常细,在屏幕上的投影经常连一个像素都不到。Arnold里有个专门的参数叫Min Pixel Width,在Arnold Renderer的Global Attributes里,默认值是0.25?不,Arnold默认Hair Min Pixel Width是0.75左右,但实际项目里我建议改成1.0以上。这个值的作用是,当曲线在屏幕上细化到小于这个宽度时,强制它保持一个最小像素宽度,避免细发丝因为欠采样而闪烁或者消失。缺点是值开太大,头发边缘会显得虚糊,远看像毛边。做近景特写时我一般设0.5到0.75,做中远景角色时设1.0到1.25,兼顾稳定性和细节。
毛发的噪点和普通几何体的噪点成因不太一样。普通模型的高频噪点大多是AA Samples不足,提高AA就能改善;但头发的暗部噪点往往来自TT透射路径的散射采样不足。如果你已经开到AA Samples 5却依然在发根和发际线看到一堆彩色颗粒,可以尝试单独提高渲染设置里的Specular Samples和Transmission Samples,这两个参数在Arnold Renderer的Ray Depth分组附近,头发相关的sample项叫Diffuse Samples。具体在MtoA里是Arnold > Rendering > Sampling,把Specular和Transmission的采样值从默认2提到3或4,噪点会非常明显地降下来。代价是渲染时间增长,但只要不是超大分辨率,这个代价是值得的。
另外,头发的最大透明深度Max Transparent Depth也要关注。这个值控制透明材质(比如头发这种半透明纤维)在一条光线穿过多层之后还能不能继续穿透,默认值是8。想象一下:一个长发角色,脑后还有披散的头发,一条光线射出要穿过十几根发丝才能到达眼睛,如果Transparent Depth不够,穿过前面几根之后就被当成不透明处理了,结果是头发深处堆出一团越来越死的黑色。长发角色要把Transparent Depth设到16以上,不然深层发丝暗部就很难看。
4.3 AOV分层:把头发单独“抠”出来调是后期神器
做角色渲染时,我几乎一定会把头发相关的光影单独分层,方便后期在合成软件里单独控制头发的亮度、对比度和色调。Arnold的AOV里,Specular和Transmission会分别记录材质的高光分量和透射分量,所以你可以在Arnold AOV设置里单独加入specular、transmission、coat这样几个AOV。导出之后,在合成软件里你会发现头发的透射信息是独立的一张层,可以单独给头发加冷暖对比,或者单独降低发缝部位的过亮透光,而完全不影响皮肤和衣服。
还有一种更粗暴但高效的做法:给头发单独指定一个ShaderOverride。在Arnold的Renderer Globals里可以挂一个Overall Shader Override,如果你不想单独输出AOV,可以先复制一份头发的Maya材质,改成平涂的纯色(通常是中等灰或者白色),用Override赋给所有头发几何,渲染出一张头发专属的阴影/遮挡通道,用来在合成里做选区或者做单独的调色蒙版。这个方法在广告项目里极其常用,因为艺术指导经常在后期要求“头发能不能再亮一档”“发梢能不能暖一点”,有了独立通道,这些改动都变成了一键操作。
5. Maya 2022环境下三个让人白调一晚的隐形坑
最后一章聊三个特别容易让人抓狂的环境问题,它们和aistandardhair本身无关,但遇到之后会让你怀疑自己所有的材质参数都白调了。
5.1 贴图颜色空间不对,发色永远调不准
Maya 2022里的Arnold对贴图颜色空间非常敏感。如果你用了一张带颜色的漫反射贴图去控制头发的Base Color或Dye Color,但贴图的Color Space还停留在Raw,那么渲染出的发色会明显偏离你在PS里看到的颜色,往往是偏灰或者偏粉。给头发用的颜色类贴图,一律要到File节点里把Color Space设为sRGB;而如果某张贴图是控制Melanin、Transmission、Roughness这类数值的参数贴图,Color Space必须设为Raw,也就是不经过任何Gamma转换。
这个原则在Maya 2022里尤其容易被忽略,因为Maya的默认颜色管理在2022版本中引入了OpenColorIO,早期版本或者某些DCC之间流转的工程文件里,贴图的颜色空间标记可能没有被正确迁移。我见过不止一次,同事从旧项目拷过来的头发Shading Network,贴图的Color Space全部是默认的Raw,导致调出来的发色明度虚高,怎么都压不回来。每次新项目开始,第一步检查所有贴图节点的Color Space,这个习惯能帮你省下一整晚。
5.2 Python版本和MtoA的隐性冲突:菜单和渲染器“神秘失踪”
Maya 2022在Maya版本序列里是个特殊存在:它是最后一个默认使用Python 2.7的版本,之后Maya 2023才全面切到Python 3。MtoA插件本身在2022下运行没问题,但如果你在这台机器上额外装过用Python 3写的第三方插件或脚本,它们可能在启动时和MtoA的Python模块产生冲突,表现是:Arnold菜单消失、或者渲染设置里找不到Arnold Renderer、或者aistandardhair节点能创建但打开属性编辑器时会报一个“UnicodeDecodeError”之类的Python错误。
处理方式我建议按顺序排查:先检查Plug-in Manager里MtoA.mll是否正常加载,状态是Loaded而不是Unloaded;再去Maya的Python脚本目录里看有没有某个插件在userSetup.py里强行设置过系统环境变量,如果有,试着把userSetup.py临时改名重启Maya确认是不是它引起的;最后可以考虑在启动Maya前,给系统环境变量里设置一个MAYA_DISABLE_CIP=1来解决旧版CIP和Python 2的一些兼容问题。多数情况到第二步就能定位凶手。
5.3 缺少OpenColorIO配置文件导致色彩管理“假死”
Maya 2022的Color Management设置里,默认的OCIO配置如果缺失,会让你的渲染视口和最终Arnold输出颜色完全错乱:材质球看起来是正常的,但渲染结果是整体偏品红或者整体偏绿。这个问题的元凶经常是安装Maya时没有带上完整的OCIOC配置文件,或者你手动指定了一个不存在的config.ocio路径。最典型的热搜场景就是Maya里渲染时提示“Color Manager: Could not find OCIO config”之类的报错,或者没有任何报错但画面颜色就是不对。
解决办法是先查看窗口菜单Window > Settings/Preferences > Color Management,把Color Management Enabled勾选状态确认一下,然后将Default Output Transform改成Maya Default或Utility Linear。如果你确实想用ACES流程,就去OpenColorIO官网下载一份ACES的config.ocio文件,放到本地目录,然后在这个设置面板的Specify OCIO Config里指向那个文件。我个人遇到更多的情况是,项目组同事因为装了某个第三方渲染农场插件,把全局的OCIO环境变量改掉了,导致Maya里的颜色管理显示异常。所以,如果你发现之前正常的场景隔天突然偏色,先怀疑环境变量而不是你的材质——这种“不是你的锅但你必须解决”的问题,最需要的就是从上到下排查一遍环境设置。
最后再分享一个可能帮你省很多时间的小技巧。做复杂角色的头发时,先用一个低分辨率的Proxy球体,把某一撮头发的Shader参数调好,拍到满意的静帧后,再批量把这个Shader复制给所有头发组。不要一开始就在完整角色上反复测试渲染,头发计算本身就慢,一帧可能就要几分钟,等十几次迭代下来,你大部分时间都耗在等待上了。aistandardhair的优势在于它的参数直觉性很强,理解了两条高光的光路模型之后,你甚至可以只靠看渲染的Specular AOV就判断出该往哪个方向调,真正的效率提升不是在某个技巧里,而是对整个头发光路体系建立直觉的过程。
