【节点】[TangentVector节点]原理解析与实际应用

0 阅读11分钟

【Unity Shader Graph 使用与特效实现】专栏-直达

在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 使用与特效实现】专栏-直达 (欢迎点赞留言探讨,更多人加入进来能更加完善这个探索的过程,🙏)