用ShaderGraph零代码实现皮肤次表面散射效果
在游戏角色渲染中,皮肤材质的表现一直是技术难点之一。传统着色器难以模拟光线在皮肤组织中的复杂散射行为,导致角色看起来像塑料或蜡像。次表面散射(Subsurface Scattering, SSS)技术正是解决这一问题的关键,它能够再现光线穿透半透明材质后在内部散射的物理现象,为皮肤、玉石等材质带来真实的视觉质感。
本文将完全基于Unity的ShaderGraph可视化工具,从物理原理出发,通过节点连接的方式构建完整的SSS效果,无需编写一行代码。相比传统需要记忆复杂公式的Shader编程方式,这种方法让技术美术师和Shader初学者能够直观地理解每个计算步骤的物理意义,快速获得可用于实际项目的可视化Shader资源。
1. 次表面散射的核心原理
次表面散射是指光线进入材质表面后,在内部经过多次散射最终从不同位置射出的光学现象。对于皮肤材质,这种效应主要表现在三个关键视觉特征上:
- 边缘透光效果:当强光从背面照射时,耳朵、鼻翼等较薄部位会呈现红色透光
- 柔和阴影过渡:皮肤表面的明暗交界处会呈现模糊的红色调过渡
- 深度感:皮肤表面下会呈现微妙的光线渗透感,而非完全停留在表面
在ShaderGraph中实现这些效果,我们需要重点关注两个核心计算:
- 背光透射(BTDF):模拟光线穿过物体从另一侧射出的效果
- 表面散射(BSSRDF):模拟光线进入表面后在附近区域重新射出的效果
提示:虽然真实世界的SSS是复杂的光物理过程,但在实时渲染中我们只需要近似这些视觉效果,不必完全模拟物理规律。
2. ShaderGraph环境准备
在开始构建SSS效果前,需要确保项目环境配置正确:
2.1 创建ShaderGraph资源
- 在Unity项目中右键点击Create > Shader > Universal Render Pipeline > Sub Graph
- 将新建的子图命名为"SSS_Core"
- 打开ShaderGraph编辑器,确认使用的是URP模板
2.2 关键节点准备
实现SSS效果需要以下几个核心节点:
| 节点类型 | 功能描述 | 物理对应 |
|---|---|---|
| Dot Product | 计算向量点积 | 光线与表面法线夹角 |
| Power | 指数运算 | 散射强度衰减 |
| Lerp | 线性插值 | 材质厚度影响 |
| Sample Texture 2D | 采样厚度图 | 物体局部厚度 |
这些节点将通过特定方式连接,模拟光线在材质内部的散射行为。
3. 构建背光透射(BTDF)效果
背光透射是SSS最显著的特征,我们首先在ShaderGraph中实现这一效果。
3.1 基础背光计算
创建三个Vector3类型的属性:
LightDirection:光源方向ViewDirection:观察方向Normal:表面法线
使用Dot Product节点计算背光强度:
Dot(-LightDirection, ViewDirection)这模拟了光线从背面穿透物体后进入眼睛的基本强度。
添加Power节点控制散射锐利度:
Power(DotResult, ScatterPower)其中
ScatterPower是控制参数,值越大透光区域越集中。
3.2 法线扰动模拟折射
真实光线穿透材质时会发生折射,我们需要在ShaderGraph中近似这一现象:
- 创建Float类型属性
RefractionStrength控制折射强度 - 使用以下节点链模拟折射方向:
Add(LightDirection, Multiply(Normal, RefractionStrength)) Normalize(AddResult) - 将结果用于背光计算:
Dot(-RefractedLight, ViewDirection)
这样得到的背光效果会更接近真实皮肤在不同角度下的透光表现。
3.3 厚度图控制透光强度
物体不同部位的透光程度取决于其厚度,我们需要引入厚度图控制效果:
- 创建Texture2D类型属性
ThicknessMap - 添加Sample Texture 2D节点采样厚度图
- 使用Lerp节点混合背光效果:
薄区域(厚度值小)会显示更强的透光效果Lerp(0, BTDF_Intensity, ThicknessSample)
4. 实现表面散射(BSSRDF)效果
表面散射使皮肤在直接光照下呈现特有的柔和质感,我们通过以下步骤实现:
4.1 基础漫反射改造
- 使用标准NdotL计算作为基础:
Dot(Normal, LightDirection) - 添加Wrap Lighting效果模拟散射:
其中Divide(Add(NdotL, WrapFactor), Add(1, WrapFactor))WrapFactor控制散射范围,值越大明暗交界处越柔和
4.2 添加散射颜色影响
皮肤散射会偏向红色调,需要特别处理:
- 创建Color类型属性
ScatterColor - 使用SmoothStep节点定义散射区域:
SmoothStep(0, ScatterWidth, NdotL_Wrap) - 混合散射颜色到最终结果:
Add(Diffuse, Multiply(ScatterMask, ScatterColor))
4.3 高光反射调整
皮肤高光需要特殊处理以匹配SSS效果:
- 使用比常规材质更宽的镜面反射
- 降低高光强度,避免塑料感
- 可添加第二层微表面高光模拟皮肤油脂层
5. 完整节点图整合与参数调节
将BTDF和BSSRDF效果整合为完整的SSS着色器:
5.1 节点图结构
完整的ShaderGraph应包含以下主要部分:
属性输入区:
- 光源、视角、法线等基础输入
- 厚度图、散射颜色等材质参数
- 强度、范围等调节参数
BTDF计算分支:
- 背光透射强度计算
- 折射扰动处理
- 厚度图控制
BSSRDF计算分支:
- 包裹漫反射
- 散射颜色混合
- 特殊高光处理
最终合成:
- 根据视角方向混合两种效果
- 环境光遮蔽影响
- 最终颜色输出
5.2 关键参数调节建议
| 参数 | 推荐值 | 效果说明 |
|---|---|---|
| ScatterPower | 2-5 | 控制背光锐利度 |
| RefractionStrength | 0.3-0.7 | 折射扭曲程度 |
| WrapFactor | 0.4-0.8 | 表面散射柔和度 |
| ScatterWidth | 0.2-0.4 | 散射颜色影响范围 |
在实际项目中,这些参数需要根据具体美术风格和光照条件进行调整。测试时建议从默认值开始,逐步微调直到获得满意的视觉效果。
6. 性能优化与平台适配
将SSS效果应用于实际项目时需要考虑性能因素:
6.1 移动端优化技巧
- 简化厚度图精度,使用512x512或更低
- 降低BTDF计算精度,减少采样次数
- 在低端设备上关闭折射扰动计算
- 使用预计算的散射颜色代替实时混合
6.2 多平台参数预设
创建不同的参数预设以适应各平台:
[Presets] - HighEnd_PC: - ScatterSamples: 4 - RefractionQuality: High - Mobile_MidRange: - ScatterSamples: 2 - RefractionQuality: Low - Mobile_LowEnd: - Disable_BTDF - Simple_WrapLighting这种分级策略可以确保在不同硬件上都能获得最佳的性能与质量平衡。