目录
1. 与法线混合节点(Normal Blend Node)配合
2. 与高度转法线节点(Normal From Height Node)配合
一、节点功能概述
法线强度节点(Normal Strength Node)是 Unity Shader Graph 中用于调整法线贴图凹凸强度的专用工具。它通过数学变换修改法线向量的 XY 分量(切线空间中的水平偏移),同时保持 Z 分量的稳定性,从而在不破坏法线单位向量性质的前提下,实现凹凸效果的强弱控制。该节点在材质细节调整、性能优化和动态效果制作中具有重要作用,核心优势在于:
- 精确强度控制:通过 Strength 参数线性调节法线凹凸程度(0-1 范围)
- 物理正确性:保持法线向量归一化,确保光照计算准确
- 无损调整:强度为 1 时完全保留原始法线信息
二、端口与参数详解
2.1 端口配置
端口名称 | 方向 | 数据类型 | 描述 |
---|---|---|---|
In | 输入 | Vector 3 | 待调整的法线向量(切线空间) |
Strength | 输入 | Float | 强度值(0-1,0 为平坦法线) |
Out | 输出 | Vector 3 | 调整后的法线向量 |
2.2 核心参数逻辑
- Strength=0: 输出平坦法线
(0, 0, 1)
,消除所有凹凸效果 - Strength=1: 输出原始法线,无任何修改
- 0<Strength<1: 按比例缩小法线的 XY 分量,减弱凹凸效果
三、技术原理解析
3.1 数学公式推导
3.2 生成代码解析
hlsl
void Unity_NormalStrength_float(float3 In, float Strength, out float3 Out)
{
Out = float3(In.rg * Strength, lerp(1, In.b, saturate(Strength)));
}
代码关键点:
- XY 分量处理:直接乘以 Strength,线性缩放凹凸偏移量
- Z 分量处理:使用
lerp(1, In.b, saturate(Strength))
确保:- Strength=0 时 Z=1(平坦法线)
- Strength=1 时 Z=In.b(原始法线)
- 数值稳定性:
saturate(Strength)
将强度限制在 [0,1] 范围
四、应用场景与实战案例
4.1 材质细节动态调节
场景:武器磨损程度可视化
- 需求:随使用时间增加,武器表面划痕细节逐渐减弱
- 实现:
csharp
// C#脚本控制强度 float wearProgress = GetWearProgress(); // 0-1 material.SetFloat("_NormalStrength", 1 - wearProgress);
- 效果:新武器细节清晰,磨损后凹凸效果减弱
4.2 性能优化策略
场景:移动端 LOD 切换
- 需求:远距离物体使用低强度法线,减少光照计算开销
- 策略:
- 远距离:Strength=0.5
- 中距离:Strength=0.8
- 近距离:Strength=1
- 优势:在视觉损失可接受的前提下,降低 GPU 负载
4.3 动态变形效果
场景:角色肌肉膨胀动画
- 需求:角色发力时肌肉法线强度增强
- 实现:
hlsl
// Shader中结合动画参数 float muscleIntensity = _Time.y * 0.5; // 模拟肌肉收缩动画 float3 adjustedNormal = Unity_NormalStrength_float(baseNormal, muscleIntensity);
五、使用技巧与注意事项
5.1 强度与光照关系
- 强度变化会影响表面光照的高光和阴影:
- 高强度:高光区域更小、更锐利
- 低强度:高光区域更大、更柔和
5.2 与其他节点配合
1. 与法线混合节点(Normal Blend Node)配合
hlsl
float3 baseNormal = UnpackNormal(_BaseNormalMap);
float3 detailNormal = UnpackNormal(_DetailNormalMap);
float3 blendedNormal = Unity_NormalBlend_float(baseNormal, detailNormal);
float3 finalNormal = Unity_NormalStrength_float(blendedNormal, _DetailStrength);
2. 与高度转法线节点(Normal From Height Node)配合
hlsl
float height = tex2D(_HeightMap, uv).r;
float3 normal = Unity_NormalFromHeight_Tangent_float(height, _HeightStrength);
normal = Unity_NormalStrength_float(normal, _FinalStrength);
5.3 常见问题解决
- 法线方向反转: 若出现光照异常,尝试反转 XY 分量:
hlsl
Out = float3(-In.rg * Strength, lerp(1, In.b, saturate(Strength)));
- 精度损失: 高强度值下若细节丢失,可增加法线贴图精度或使用半精度浮点
六、总结与拓展应用
法线强度节点通过简洁的数学变换,实现了对法线贴图凹凸效果的精确控制,其核心价值在于:
- 创作灵活性:无需修改美术资源,即可实时调整材质细节
- 性能可控性:通过强度降低减少光照计算复杂度
- 动态适应性:支持根据游戏状态(如距离、时间)动态调整
拓展方向:
- 结合噪声纹理实现程序性强度变化(如岩石表面的自然磨损)
- 在 VR 中根据用户视角距离自动调整法线强度,优化性能
- 开发基于物理的强度模型,模拟不同材质的凹凸衰减特性