在Unity的Shader Graph中,TangentVector节点是一个基础且重要的工具,它允许着色器开发者访问网格的切线矢量信息。切线矢量在计算机图形学中扮演着关键角色,特别是在实现各种高级渲染效果时,如法线贴图、视差映射、各向异性光照等。深入理解TangentVector节点的原理和应用,对于创建高质量的着色器至关重要。
TangentVector节点基础概念
TangentVector节点是Shader Graph中用于获取网格切线信息的核心节点。切线是定义在网格每个顶点上的矢量,它与法线和副切线(又称副法线或双切线)共同构成了每个顶点的局部坐标系系统,这个系统通常被称为切线空间。
切线空间是一个局部坐标系,对于每个顶点都是唯一的:
- 法线矢量指向顶点表面的垂直方向
- 切线矢量通常沿着纹理坐标的U方向
- 副切线矢量通过法线和切线的叉积得到,通常沿着纹理坐标的V方向
在Shader Graph中使用TangentVector节点时,可以通过Space参数选择四种不同的坐标空间输出切线矢量:Object空间、View空间、World空间和Tangent空间。每种空间都有其特定的应用场景和计算方式。
端口与参数详解
![]()
输出端口
TangentVector节点只有一个输出端口,标记为"Out",输出类型为Vector 3。这个端口输出的矢量表示网格在指定空间中的切线方向。
- 输出矢量的三个分量分别对应X、Y、Z坐标
- 输出值的范围取决于选择的坐标空间
- 在Tangent空间下,切线通常指向纹理坐标的U正方向
Space参数选项
Space参数是TangentVector节点最关键的配置选项,它决定了切线矢量输出的坐标空间:
- Object空间:相对于物体自身坐标系的切线方向
- View空间:相对于摄像机视角坐标系的切线方向
- World空间:相对于世界坐标系的切线方向
- Tangent空间:相对于顶点切线空间的切线方向
坐标空间深入解析
Object空间切线
Object空间切线是相对于物体自身局部坐标系的切线矢量。在这种空间下,切线方向不会随着物体的旋转或移动而改变,只与物体自身的几何结构相关。
Object空间切线的特点:
- 与物体的世界变换无关
- 在物体不发生形变的情况下保持不变
- 适用于需要基于物体自身几何特性的效果
使用Object空间切线的典型场景:
- 基于物体几何的条纹效果
- 物体表面的流动图案
- 与物体形状相关的变形效果
View空间切线
View空间切线是相对于摄像机坐标系的切线矢量。在这种空间下,切线方向会随着摄像机的移动和旋转而变化。
View空间切线的特点:
- 相对于摄像机视角
- 随着摄像机移动而变化
- 在屏幕空间中具有一致性
使用View空间切线的典型场景:
- 屏幕空间效果
- 与视角相关的反射
- 基于视角的材质变化
World空间切线
World空间切线是相对于世界坐标系的切线矢量。这种空间下的切线方向在世界中是固定的,不会随着物体或摄像机的移动而改变。
World空间切线的特点:
- 在世界坐标系中固定
- 与物体的位置和旋转相关
- 适用于需要世界一致性的效果
使用World空间切线的典型场景:
- 世界坐标对齐的纹理映射
- 全局风向影响的植被
- 与世界方向相关的光照计算
Tangent空间切线
Tangent空间切线是相对于顶点自身切线空间的切线矢量。在Tangent空间中,切线通常指向纹理坐标的U正方向,法线指向表面外侧,副切线通过法线和切线的叉积得到。
Tangent空间切线的特点:
- 相对于每个顶点的局部坐标系
- 通常指向纹理U方向
- 是法线贴图的标准空间
使用Tangent空间切线的典型场景:
- 法线贴图计算
- 切线空间下的光照计算
- 需要与纹理坐标对齐的效果
切线空间与法线贴图
切线空间基础
切线空间是一个每个顶点独有的局部坐标系,由三个相互垂直的矢量组成:
- 切线:通常指向纹理坐标的U正方向
- 法线:垂直于表面指向外侧
- 副切线:通过法线和切线的叉积得到,通常指向纹理坐标的V正方向
在Shader Graph中,可以通过组合使用TangentVector、NormalVector和Cross Product节点来构建完整的切线空间变换矩阵。
法线贴图原理
法线贴图是切线空间最经典的应用。法线贴图中存储的不是颜色信息,而是每个纹素在切线空间中的法线方向。使用法线贴图可以在不增加几何复杂度的前提下,为表面添加丰富的细节。
法线贴图的工作流程:
- 从法线贴图中提取切线空间法线
- 将切线空间法线转换到世界空间或其他所需空间
- 使用转换后的法线进行光照计算
在Shader Graph中实现法线贴图的典型节点连接:
- 使用Sample Texture 2D节点采样法线贴图
- 使用Normalize节点确保法线长度为1
- 使用Transform节点将法线从切线空间转换到世界空间
- 将世界空间法线连接到光照计算节点
切线空间转换
将矢量从切线空间转换到其他空间需要构建TBN矩阵(Tangent, Bitangent, Normal矩阵)。TBN矩阵是一个3x3的旋转矩阵,可以将切线空间中的矢量转换到目标空间。
在Shader Graph中构建TBN矩阵的方法:
- 使用TangentVector节点获取切线矢量
- 使用NormalVector节点获取法线矢量
- 使用Cross Product节点计算副切线矢量
- 使用Matrix Construction节点构建TBN矩阵
将切线空间法线转换到世界空间的公式:
世界空间法线 = TBN矩阵 × 切线空间法线
高级应用与技术
视差映射
视差映射是一种增强表面深度感的技术,它通过根据视角偏移纹理坐标来模拟表面凹凸。切线空间在视差映射中起到关键作用,因为深度偏移需要在切线空间中进行计算。
视差映射的基本步骤:
- 在切线空间中计算视角方向
- 根据高度图进行纹理坐标偏移
- 采样偏移后的纹理坐标
在Shader Graph中实现视差映射:
- 使用Tangent Vector和Normal Vector节点构建切线空间
- 将视角方向转换到切线空间
- 根据高度图偏移纹理坐标
- 使用偏移后的坐标采样颜色和法线贴图
各向异性光照
各向异性光照用于模拟表面在不同方向上反射光线不同的材质,如拉丝金属、头发和丝绸等。切线方向在这些效果中定义了各向异性的方向。
各向异性光照的实现要点:
- 使用切线方向确定各向异性轴线
- 根据视角与切线方向的角度计算高光
- 通常使用专门的光照模型,如Ward或Ashikhmin-Shirley模型
在Shader Graph中创建各向异性高光:
- 使用TangentVector节点获取切线方向
- 计算视角方向与切线方向的角度
- 使用自定义函数节点实现各向异性高光计算
- 将结果与基础颜色混合
毛发渲染
毛发渲染是各向异性光照的一个特殊应用。在毛发渲染中,切线方向沿着毛发生长的方向,这对于模拟毛发的光泽和高光至关重要。
毛发渲染的关键技术:
- 使用切线方向定义毛发生长方向
- 实现基于切线方向的高光计算
- 使用多层高光模拟毛发的复杂反射特性
- 结合透明度测试实现毛发的轮廓效果
流动效果
切线空间可用于创建沿着表面几何流动的效果,如水流过岩石表面或能量在物体表面流动。通过结合时间因子和切线方向,可以实现自然的方向性流动。
流动效果的实现方法:
- 使用切线方向确定流动主方向
- 使用时间节点创建动画效果
- 结合噪声纹理增加流动的自然感
- 使用UV扭曲技术增强视觉效果
性能优化与最佳实践
性能考虑
使用TangentVector节点时需要考虑的性能因素:
- 不同坐标空间的计算开销不同
- Tangent空间转换需要额外的矩阵运算
- 在移动平台上应谨慎使用复杂的切线空间计算
- 考虑使用预计算的数据减少实时计算
优化建议:
- 在不需要精确切线方向的场合使用更简单的近似
- 避免在片段着色器中进行复杂的切线空间转换
- 使用适当的精度修饰符(half或fixed)减少计算开销
- 考虑使用静态切线方向代替动态计算
常见问题与解决方案
使用TangentVector节点时可能遇到的常见问题:
切线方向不正确
- 检查模型的导入设置,确保生成了正确的切线
- 验证UV布局,切线方向通常与UV的U方向对齐
- 在建模软件中检查模型的UV展开和切线设置
法线贴图效果错误
- 确认法线贴图的颜色空间设置(通常是线性空间)
- 检查TBN矩阵的构建是否正确
- 验证法线转换的方向和空间一致性
各向异性效果不自然
- 调整切线方向的缩放和强度
- 检查光照计算中的方向一致性
- 考虑使用副切线方向作为备选方向
最佳实践
有效使用TangentVector节点的最佳实践:
正确设置模型数据
- 在建模软件中确保UV展开合理
- 在Unity导入设置中启用切线生成
- 对于特殊用途的模型,考虑自定义切线方向
合理的节点组织
- 将切线空间计算封装在Sub Graph中提高复用性
- 使用注释和分组保持Shader Graph的可读性
- 为不同的坐标空间使用创建专门的工具节点
测试与验证
- 使用简单的测试材质验证切线方向
- 创建可视化工具检查各空间下的切线矢量
- 在不同设备和平台上测试效果的一致性
实际案例与示例
基础法线贴图实现
创建一个使用TangentVector节点的基础法线贴图着色器:
节点设置:
- 添加TangentVector节点,Space设置为Tangent
- 添加NormalVector节点,Space设置为Tangent
- 添加Sample Texture 2D节点,连接法线贴图
- 使用Normal Reconstruct Z节点重建法线的Z分量
- 使用Transform节点将法线从Tangent空间转换到World空间
- 将世界空间法线连接到Master节点的Normal输入
关键步骤详解:
- 法线贴图通常存储切线空间法线的XY分量,Z分量需要通过计算重建
- 使用Normal Reconstruct Z节点根据XY分量计算Z分量
- 确保法线转换的方向正确,特别是当使用DirectX风格的法线贴图时
各向异性高光着色器
创建一个模拟拉丝金属的各向异性高光着色器:
节点设置:
- 添加TangentVector节点,Space设置为World
- 添加View Direction节点,Space设置为World
- 使用Dot Product节点计算视角方向与切线方向的角度
- 使用Anisotropic Specular函数节点计算高光强度
- 将高光结果与基础颜色混合
各向异性高光函数:
- 使用切线方向作为各向异性轴线
- 根据视角与切线的角度计算高光分布
- 通常使用椭圆形状的高光模型模拟各向异性反射
视差遮挡映射
创建一个增强版的视差效果——视差遮挡映射:
节点设置:
- 添加TangentVector节点,Space设置为Tangent
- 添加View Direction节点,使用Transform节点转换到Tangent空间
- 实现多层层叠的深度测试模拟遮挡效果
- 根据深度测试结果混合不同层的纹理采样
技术要点:
- 视差遮挡映射比基础视差映射更真实地表现深度关系
- 通过多次采样模拟光线在凹凸表面的传播
- 需要平衡效果质量和性能开销
【Unity Shader Graph 使用与特效实现】专栏-直达 (欢迎点赞留言探讨,更多人加入进来能更加完善这个探索的过程,🙏)