1. 为什么皮肤、蜡烛和牛奶在HDRP里总像塑料
很多人第一次在HDRP里做角色特写,都会遇到同一个尴尬:模型精度拉满、贴图分辨率拉到4K、法线细节也雕得挺细,可皮肤一打光就透着一股塑料味。尤其是耳朵、鼻翼、指尖这些薄的地方,光打上去要么死黑,要么像涂了一层蜡。问题往往不在贴图,也不在灯光,而是材质模型选错了——你用的是标准PBR的金属/高光工作流,而真实皮肤、玉石、蜡烛、牛奶这类材质,光线不只是从表面反射,还会钻进材质内部,在里面散射一段距离之后再从别的点钻出来。
这个“钻进内部再散射出来”的物理现象,就是次表面散射(Subsurface Scattering,简称SSS)。HDRP里对它的支持算是比较完整的,但坑也集中:不同版本的HDRP对SSS的实现方式改过好几轮,材质面板上的参数含义也换过,网上很多教程还是老版本的截图,照着调很容易调出一脸“油光”或者“死白”。这篇内容我打算把HDRP里SSS的几种实现路径、参数背后的物理含义、以及实际项目里怎么调才不翻车,从头到尾捋一遍。适合已经会用HDRP基础材质、但一碰到皮肤/玉石/半透材质就发怵的开发者,也适合想搞清楚“为什么参数这么设”的技术美术。
先说结论:HDRP里做SSS,核心不是把某个滑块拉满,而是先判断你的材质属于哪一类散射行为,再选对应的Shader和参数组合。选错了模型,后面怎么调都是白费劲。
2. HDRP里SSS的三种实现路径与选型逻辑
HDRP并没有只给一个“SSS开关”就完事,它实际上提供了几种不同精度的散射方案,分别对应不同的材质类型和性能预算。你得先搞清楚自己要做的东西属于哪一类,再去选路径。
2.1 扩散剖面(Diffusion Profile):所有SSS的公共基础
不管后面用哪种Shader,HDRP里做SSS都绕不开一个东西——扩散剖面(Diffusion Profile)。你可以把它理解成一张“光线在材质内部能跑多远、怎么衰减”的配方表。它本质上是一组参数,描述了红、绿、蓝三个通道各自的散射半径和衰减形状。
为什么是三个通道分开?因为真实材质对不同波长的吸收不一样。皮肤之所以偏红,就是因为红光在皮肤里散射距离最远,绿光次之,蓝光最容易被吸收。所以扩散剖面里你会看到类似“Scattering Distance”这种按RGB分别设置的字段。把红色通道的距离设大,材质透光就偏红;三个通道设成一样,透出来就是灰白的,像牛奶或者某些玉石。
在HDRP的Project Settings或者Volume里可以创建Diffusion Profile资源,一个项目里最多能挂多少个是有上限的(不同版本数量不同,早期是16个左右)。这个上限很关键,因为它直接决定了你项目里能有多少种不同的散射材质。如果你有十个角色,每个角色皮肤散射参数都不一样,那就要提前规划,能复用就复用。
提示:Diffusion Profile是项目级资源,不是材质级参数。很多人调半天材质没反应,是因为根本没指定Diffusion Profile,或者指定的那个资源没被正确引用。
2.2 次表面散射Shader:适合皮肤、玉石这类“厚”材质
HDRP的Lit Shader里有一个Subsurface Scattering模式,这是最常用的路径。它适合有一定厚度、散射比较均匀的材质,比如人物皮肤、玉石、象牙、蜡烛。
这个模式下的关键参数有几个:Scattering Distance(散射距离,由Diffusion Profile决定)、Transmission(透射,控制光线穿透的强度)、Thickness(厚度贴图,控制不同区域的散射强度)。其中Thickness贴图是最容易被忽略但最影响效果的一环。比如耳朵边缘薄,光容易透过来,Thickness贴图对应区域就应该偏白(表示薄);脸颊厚,就偏黑。如果你不给Thickness贴图,整个模型散射均匀,耳朵和脸颊一个样,看起来就假。
我自己的习惯是:先在Substance Designer或者手绘一张灰度Thickness贴图,耳朵、鼻翼、指尖这些地方画白,脸颊、额头画黑,然后接到材质对应的槽里。这一步做完,SSS的立体感立刻就出来了。
2.3 透射(Transmission)模式:适合玻璃、水、薄片类材质
如果你的材质是玻璃、水、薄塑料片这种“光直接穿过去”的类型,那用的不是SSS,而是Transmission模式。它和SSS的区别在于:SSS是光在内部散射后再出来,方向被打乱;Transmission是光基本沿原方向穿透,只是被折射和吸收。
HDRP的Lit Shader里Transmission和SSS是两个不同的选项,别混用。有人做玻璃的时候开了SSS,结果玻璃看起来像磨砂塑料,就是因为散射把方向打乱了。玻璃要的是清晰透射,不是散射。
2.4 选型对照表
| 材质类型 | 推荐模式 | 关键参数 | 常见错误 |
|---|---|---|---|
| 人物皮肤 | Subsurface Scattering | Thickness贴图、Scattering Distance | 不给Thickness,散射均匀 |
| 玉石/象牙 | Subsurface Scattering | 高Transmission、中等散射距离 | 散射距离设太大,整体发糊 |
| 蜡烛/蜡 | Subsurface Scattering | 中等散射、偏黄Diffusion Profile | 用纯白Profile,透光发灰 |
| 玻璃/水 | Transmission | 折射率、吸收颜色 | 误开SSS,失去清晰透射 |
| 牛奶/浑浊液体 | Subsurface Scattering | 三通道距离接近、高散射 | 距离设太小,看起来像塑料 |
这张表是我自己在项目里反复踩坑后总结的,选型对了,后面调参就是微调;选型错了,怎么调都别扭。
3. 扩散剖面的参数到底在描述什么物理量
很多人调Diffusion Profile是“凭感觉拖滑块”,拖到看着顺眼就停。但如果你知道每个参数背后的物理含义,调起来会快很多,也更容易在不同材质之间迁移经验。
3.1 Scattering Distance:光在材质里平均能跑多远
Scattering Distance是扩散剖面里最核心的参数,单位是场景单位(一般是米)。它描述的是光在材质内部散射时,平均能传播多远。数值越大,光透得越深,材质看起来越“厚实通透”;数值越小,光刚进去就被吸收了,材质看起来越“实”。
这里有个容易搞混的点:Scattering Distance不是“厚度”,而是“散射特征长度”。真实皮肤的散射距离大概在几毫米到一厘米量级,但你在HDRP里如果按真实比例设,模型也得按真实比例做,否则效果对不上。很多项目里角色模型不是1:1米制,这时候就要按比例缩放散射距离,不然要么透得太夸张,要么完全看不出透光。
我的经验是:先确认模型比例,再按“耳朵厚度”去反推散射距离。比如耳朵实际厚度2毫米,模型如果放大到2厘米,那散射距离也要相应放大,否则光透不过去。
3.2 三通道分离:为什么红色总是跑得最远
扩散剖面里RGB三个通道是分开设的,这不是为了好玩,而是因为真实材质的吸收光谱不同。以皮肤为例,黑色素和血红蛋白对蓝绿光的吸收远强于红光,所以红光在皮肤里能跑得更远,透出来就偏红。
在HDRP里,如果你把三个通道设成一样,透光就是中性灰白,适合牛奶、某些玉石。如果要做皮肤,通常红色通道距离最大,绿色次之,蓝色最小。具体比例没有绝对标准,但一个常见的起点是红:绿:蓝大约在 1 : 0.5 : 0.25 左右,然后根据角色肤色微调。偏白皮肤可以整体缩短距离,偏深肤色可以进一步压缩蓝绿通道。
注意:不要直接把红色通道拉到极大,否则耳朵会透得像红灯,非常假。散射是“柔和透光”,不是“发光”。
3.3 散射半径与衰减形状的配合
除了距离,扩散剖面还控制衰减的“形状”——光在材质里不是均匀衰减的,而是按某种分布快速衰减。HDRP内部用的是类似偶极子或高斯型的近似,你不需要自己算,但要知道:距离和衰减形状是配合的。距离设大但衰减形状很陡,光还是透不深;距离设小但衰减平缓,边缘会有一层奇怪的“光晕”。
实际调的时候,我一般先只动距离,把三个通道的比例调顺,再看边缘过渡是否自然。如果边缘出现明显色带或者硬边,多半是距离和Thickness贴图的对比度不匹配,需要回去改Thickness。
3.4 一个可复用的皮肤Profile起点
如果你不想从零调,可以试试这个起点(以米制、正常角色比例为例):
- 红色通道散射距离:0.008 到 0.012
- 绿色通道散射距离:0.004 到 0.006
- 蓝色通道散射距离:0.002 到 0.003
- 整体散射强度:中等偏上
然后配合一张Thickness贴图,耳朵、鼻翼、指尖画白,其余画黑。这个组合在多数写实角色上能出一个不错的底子,剩下的就是按角色肤色和灯光微调。记住,这只是起点,不是万能公式,灯光一变,观感就变,SSS从来不是材质单独能搞定的。
4. 厚度贴图与法线:SSS效果成败的两个隐藏开关
调SSS的时候,大部分人盯着Diffusion Profile和Transmission滑块,但真正决定“像不像”的,往往是两张贴图:Thickness贴图和法线贴图。这两张图没处理好,参数调出花来也白搭。
4.1 Thickness贴图:告诉渲染器哪里薄哪里厚
Thickness贴图是一张灰度图,白色表示该区域薄、光容易透,黑色表示厚、光透不过去。它的作用是让散射强度在模型表面有变化,而不是均匀一片。
为什么它这么关键?因为真实材质的厚度是不均匀的。耳朵边缘薄,光一打就透红;脸颊厚,光透不过去。如果你不给Thickness,HDRP默认按均匀厚度处理,结果就是整个脸一个透光度,耳朵和脸颊一样,看起来像蜡像。
制作Thickness贴图有几种常见做法:
- 手绘:在SP或者PS里按解剖结构画,耳朵、鼻翼、指尖、嘴唇画白,其余画黑。适合角色不多、要求高的项目。
- 烘焙:用DCC工具(如某些三维软件)烘焙厚度信息,适合批量处理。
- 程序化生成:用Substance Designer根据曲率或者AO反推,适合快速出底子。
我自己的习惯是手绘加烘焙结合:先烘焙一张底图,再手绘修正关键区域。纯烘焙有时候会把该薄的地方烘厚,比如鼻孔内部,需要手动压暗。
提示:Thickness贴图的对比度不要拉太满,否则散射区域和正常区域之间会出现硬边。留一点过渡,效果更自然。
4.2 法线贴图:散射方向也受表面朝向影响
法线贴图在SSS里的作用容易被低估。SSS虽然是在内部散射,但光线进入和离开表面的方向仍然受表面法线影响。如果法线贴图有错误(比如接缝、翻转、强度过大),散射出来的光也会跟着错,表现为局部过亮、过暗或者色偏。
常见问题:法线贴图强度拉太高,表面看起来凹凸不平,SSS透光时这些凹凸会被放大,出现奇怪的亮斑。我的建议是,做SSS材质时法线强度比普通PBR材质稍微收一点,尤其是皮肤,真实皮肤的法线细节很细腻,不需要夸张的凹凸。
另外,法线贴图的UV接缝处如果处理不好,SSS会在接缝处出现明显的断裂。这个在角色脸部尤其明显,因为脸部UV通常切得比较碎。解决办法是尽量把接缝藏在不容易看到的地方,或者在接缝处手动平滑法线。
4.3 Thickness和法线的配合调试流程
我一般按这个顺序调:
- 先只给基础颜色和粗糙度,确认模型和UV没问题。
- 加上法线贴图,调到自然,不夸张。
- 加上Thickness贴图,先看灰度分布是否合理。
- 指定Diffusion Profile,从保守的散射距离开始,逐步加大。
- 最后调Transmission和整体强度,配合灯光看效果。
这个顺序的好处是每一步只动一个变量,出问题容易定位。如果一上来全开,调花了眼都不知道是哪个参数的问题。
5. 实机调试:从“塑料脸”到“透光皮肤”的排查链路
理论说再多,不如走一遍实际排查过程。下面这个链路是我在项目里遇到“皮肤像塑料”时最常用的排查顺序,你可以直接照着走。
5.1 第一步:确认Shader模式选对了
先看材质用的Lit Shader是不是开了Subsurface Scattering。HDRP里这个选项在材质面板的Surface Options里,不在下面。很多人找半天找不到,是因为它在最上面的折叠栏里。确认勾选之后,下面才会出现SSS相关参数。
如果材质是Transmission模式,那SSS参数是不生效的,两者互斥。做皮肤一定要选SSS,不要选Transmission。
5.2 第二步:检查Diffusion Profile是否指定
材质面板上有一个Diffusion Profile的槽,必须指定一个项目里创建好的Profile资源。如果这里是空的,SSS参数调了也没用。指定之后,还要确认这个Profile的散射距离是不是合理。有时候Profile是默认值,散射距离极小,看起来就像没开SSS。
5.3 第三步:看Thickness贴图有没有接、接得对不对
Thickness贴图没接,或者接错了通道(有些软件导出的灰度图通道顺序不同),都会导致散射均匀或者完全没效果。检查方法很简单:把Thickness贴图单独显示,看灰度分布是不是符合预期。耳朵该白的地方白,脸颊该黑的地方黑。
如果Thickness贴图整体偏黑,散射会很弱,看起来像没开;整体偏白,散射过强,像发光。这两种都要回去改贴图。
5.4 第四步:散射距离是不是和模型比例匹配
这是最隐蔽的坑。模型如果是按厘米做的,但散射距离按米设,那光根本透不出来;反过来,模型按米做,散射距离按厘米设,光透得夸张。确认模型比例的方法:在场景里放一个1米的标准立方体,对比角色身高。如果角色身高1.7米左右,那模型就是米制,散射距离按毫米到厘米量级设;如果角色身高170个单位,那可能是厘米制,散射距离要相应放大。
5.5 第五步:灯光是不是太硬
SSS效果对灯光非常敏感。硬光(比如平行光直射)会让散射区域对比过强,看起来假;柔光(比如大面积区域光)会让散射更自然。做皮肤特写时,我一般用主光加补光的组合,主光稍微柔一点,补光从侧后方打,把耳朵和鼻翼的透光带出来。
如果灯光太硬,就算材质调对了,看起来还是像塑料。这不是材质的问题,是灯光的问题。
5.6 第六步:后处理有没有干扰
HDRP的后处理里,Bloom、Color Grading、Tonemapping都会影响SSS的观感。Bloom开太大,散射区域会糊成一团;Tonemapping曲线太陡,透光的高光会被压掉。调试SSS时,建议先把后处理关掉或者调到中性,等材质调好再逐步加后处理。
这个排查链路走下来,基本能覆盖90%的“塑料脸”问题。剩下的10%通常是模型本身的问题,比如厚度不合理、法线错误,那就得回DCC工具改了。
6. 性能账本:SSS在移动端和主机上的取舍
SSS不是免费的。它增加了着色器复杂度,尤其是屏幕空间的散射方案,开销不小。HDRP里SSS的实现方式在不同质量等级下不一样,你得根据目标平台做取舍。
6.1 不同质量等级下的SSS开销
HDRP的SSS在高质量下用的是屏幕空间散射,需要额外的渲染通道和模糊处理,开销较大;在中低质量下可能退化成更简单的近似,效果打折但性能友好。具体开销取决于分辨率、散射半径和覆盖屏幕的面积。
一个粗略的经验:在主机上,全屏SSS的开销大概在1到3毫秒之间,取决于场景复杂度;在移动端,如果强行开高质量SSS,可能直接吃掉一半帧预算。所以移动端项目通常不用屏幕空间SSS,而是用更便宜的近似,比如预积分的皮肤着色或者简单的透光模拟。
6.2 什么时候该用SSS,什么时候该省
不是所有角色都需要SSS。如果角色在画面里很小,或者游戏是快节奏的,SSS的视觉收益很低,不如把性能留给别的效果。我一般只在以下情况开SSS:
- 角色特写、过场动画、捏脸界面
- 主角且经常出现在近景
- 材质本身是玉石、蜡烛这类散射特征明显的道具
如果角色只是远景跑动,用普通PBR加一点假透光(比如在Thickness区域加一点自发光)就够了,性能省下来给阴影或者后处理更划算。
6.3 移动端的替代方案
移动端如果非要做皮肤透光,可以考虑:
- 预积分皮肤着色:把散射近似成一张查找表,运行时查表,开销极低。
- 简单透光:在薄区域用法线点乘灯光方向,加一点颜色偏移,模拟透光。
- 顶点色控制:用顶点色标记薄区域,在着色器里做简单散射。
这些方案效果不如完整SSS,但性能友好,适合移动端。HDRP本身对移动端的SSS支持有限,很多时候需要自己写Shader或者用第三方方案。
7. 那些文档不会写的SSS实操心得
最后这部分是我自己踩坑踩出来的经验,常规文档里不会写,但实际项目里很管用。
7.1 散射距离不要一次调到位
调SSS最忌讳一次把散射距离拉很大。正确做法是从小往大调,每次加一点,配合灯光看效果。因为散射距离和Thickness贴图、灯光强度是耦合的,一次调太大,你会以为是贴图问题,其实是距离过了。我一般以0.001为单位往上加,加到透光刚好自然就停。
7.2 用参考图对比,别凭记忆调
人眼对颜色的记忆很不靠谱。调SSS时,最好找一张真实皮肤透光的参考图放在旁边对比。注意看耳朵边缘的透光颜色、鼻翼的过渡、指尖的透红程度。没有参考图,很容易调出“僵尸红”或者“蜡黄”。
7.3 不同肤色需要不同的Profile
深色皮肤和浅色皮肤的散射特性不一样。浅色皮肤散射距离可以稍大,透光偏红;深色皮肤散射距离要缩短,尤其是蓝绿通道,否则透光会发灰。不要用一个Profile套所有角色,至少准备两三个变体。
7.4 散射和粗糙度要一起调
SSS材质的粗糙度不能太高,否则表面反射会盖过散射效果。皮肤粗糙度一般在0.3到0.5之间,具体看角色年龄和肤质。粗糙度太高,皮肤看起来像磨砂;太低,像油光。SSS和粗糙度是配合的,单独调一个都不对。
7.5 注意HDRP版本差异
HDRP的SSS实现改过好几次,不同版本的参数名、默认值、甚至Shader路径都可能不同。如果你照着老教程调不出来,先确认版本。我遇到过好几次,教程里的参数在新版本里已经改名或者合并了,找半天找不到。
7.6 测试场景要固定
调SSS时,测试场景的灯光、相机角度、后处理最好固定下来。如果每次都在不同场景里看效果,你会被环境干扰,调不准。我一般建一个专门的材质测试场景,固定三盏灯(主光、补光、轮廓光),相机固定角度,这样调出来的参数才可复用。
7.7 别忘了检查UV和模型厚度
有些“SSS调不出来”的问题,根源在模型。比如耳朵模型太厚,光根本透不过去;或者UV拉伸严重,Thickness贴图对不上。调材质之前,先确认模型和UV没问题,能省很多时间。
7.8 散射不是越强越好
新手容易把散射拉得很强,觉得“透光就是好”。但真实材质的散射是克制的,过度散射会让材质失去体积感,看起来像果冻。好的SSS是“隐约透光”,不是“通体发光”。调的时候多问自己:这个透光程度,真实材质会这样吗?
7.9 记录参数,建立自己的预设库
调好一个满意的皮肤Profile后,把参数记下来,存成预设。下次做类似角色,直接从预设开始微调,比从零调快得多。我自己的预设库里有“年轻女性皮肤”“中年男性皮肤”“深色皮肤”“玉石”“蜡烛”几套,覆盖大部分需求。
7.10 多和灯光师沟通
SSS效果是材质和灯光共同决定的。如果项目里有专门的灯光师,调SSS时最好一起看效果。材质师觉得对的参数,在灯光师的实际布光下可能完全不是那么回事。两边对齐,才能出好效果。
这些心得没有一条是文档里会写的,但每一条都能帮你少走弯路。SSS是个需要耐心的活儿,参数多、耦合强,但只要理解了背后的物理逻辑,加上反复实测,总能调出满意的效果。