3.1 向量运算节点族:从 Normalize 到点积


3.1 向量运算节点族:从 Normalize 到点积

本节摘要:向量是有方向与大小的量,Shader Graph 里几乎所有"跟视角、法线、表面朝向有关"的效果都靠向量运算完成。本节讲清 Normalize、Dot Product 两个核心节点,手算验证点积的性质,并用它们拼出全册第一个"效果级"节点链:菲涅尔近似。

向量在着色器里的样子

着色器处理的三类数据——位置、方向、坐标——在图里都是向量。模型表面上每一点有一条指向外方的法线(Normal),场景相机相对每一点有一个视线方向(View Direction),两者都是单位向量(长度为一)。Shader Graph 提供现成的节点直接给出它们:Normal Vector 节点与 View Direction 节点,都带一个 Space 下拉用于选择坐标空间,默认切线空间,本章先不动它。

向量能做的运算很多,但真正撑起效果大半边天的是两件事:归一化与点积。

Normalize:先把长度统一成零

归一化(Normalize)节点把任意向量缩放成"方向不变、长度为一"。为什么要在意长度?因为很多后续运算对向量长度敏感——点积的结果会随着向量变长而变大,做边缘光时模型表面某个点法线长度不一,边缘亮度就会斑驳。习惯是:参与方向比较的向量,先归一化再说。这个节点本身没有"知识点"可讲,它更像一个卫生习惯,成本可以忽略不计。

Dot Product:一个节点,半个图形学

点积(Dot Product)把两个向量压成一个标量,几何含义是"两个方向的接近程度"。对单位向量而言:方向完全一致时结果为一,互相垂直时为零,完全相反时为负一。手算公式是分量相乘再相加:

两个三维向量 A 与 B 的点积: Dot = A.x * B.x + A.y * B.y + A.z * B.z 手算例题:A = (0, 1, 0),B = (0.6, 0.8, 0) Dot = 0 * 0.6 + 1 * 0.8 + 0 * 0 = 0.8 含义:两个方向夹角约三十七度,比较接近

在图里亲手验证:画布上放一个 Normal Vector 节点和一个 View Direction 节点(都保持默认空间),都接到一个 Dot Product 节点,输出接到 2.2 节渐变图的 Lerp 的 T 端,把 UV 那条线断开。保存后看预览球:面向相机的区域被点亮、侧向相机的区域变暗——这就是点积在逐像素回答"这个点的朝向和视线方向有多接近"。

图:法线与视线方向的点积如何随位置变化

图:法线与视线方向的点积如何随位置变化

菲涅尔近似:第一个效果级节点链

把点积换个用法:不是问"这个点朝不朝向相机",而是问"这个点是不是背对相机"——背对的边缘正是轮廓所在。做法三步:点积结果取反(One Minus 节点),得到"边缘处接近一、中心接近零"的值;再接一个 Power 节点取高次幂(比如五次),把中心区压得更暗、边缘收得更窄;输出接 Base Color。保存,预览球出现一圈越靠轮廓越亮的辉光——这就是菲涅尔效应的近似,描边(5.2)、全息(5.3)、水面反光(6.5)全部建立在它上面。

顺手做第 2.2 节布置过的功课:把幂次数做成 Vector1 属性命名 EdgePower,接到 Power 节点的 exponent 输入,材质面板上拖动它,观察边缘光从"粗亮环"收紧成"细亮线"——参数与形态的对应关系,一次实验胜过十段文字。

⚠️ 两个常见错误:忘接 One Minus 导致"中心亮边缘暗",方向感完全反了;Power 的指数用了小数接近零,结果整圈泛白——指数越大边缘越细,通常取值在二到八之间。

点积的三个衍生用法

菲涅尔只是点积的第一个衍生,另外两个在案例章之前值得先认识。衍生二:朝向遮罩——法线与世界向上向量做点积再 Saturate,得到"表面朝上的程度",雪落在朝上的面、青苔长在朝北的面,都是它。衍生三:光照近似——法线与指向光源方向的点积就是 Lambert 漫反射,Unlit 图里可以自己拼一个假光照(点积乘光色加环境色),做风格化角色时比 Lit 图更可控。三个衍生共用同一个动作:拿两条向量点一下,把"夹角"变成"数值"。

问题:Dot Product 的输出怎么是负数?颜色里显示成黑色?

负数是正常的:两个方向相反时点积为负。但颜色端口的显示范围按零到一处理,负值全部截成黑。处理方式取决于需求:想要"背对的区域也参与"就先 Saturate 把负区截零;想要"背对区域反而亮"就取绝对值。先想清楚负区在效果里的语义,再决定截断还是映射——这是点积使用者从入门到熟练的分水岭题。

向量节点的空间参数一次说清

Normal Vector 与 View Direction 都有 Space 下拉,默认 Tangent。本节的菲涅尔链在默认空间下工作正常,因为两个节点在同一空间里比较才有意义。口诀记一句:参与比较的向量必须在同一空间。将来接到世界空间效果(比如按世界高度渐变)时,把两个节点的 Space 都改成 World 即可,链路其他部分不用动。空间话题 3.2 节正式展开,这里先建立"同空间才可比"的直觉。

向量族的其他常客

本节主角之外,向量族还有三个高频配角值得提前混脸熟。Distance 节点:输出两点间距离,做"靠近才显现"的效果(接近才亮的符文、按距离衰减的雾)直接可用。Length 节点:输出向量的模长,Distance 的底层积木。Projection 系节点:把一个向量投影到另一个方向上,坡面上的分量分解会用到。三者的共同点是输出都可预期、成本都在第一二档——把它们加进第 3 章的手算练习清单,向量族的弹药就齐了。

一道组合练习题收束本节

把本节知识点串成一道综合题:实现"越靠近物体边缘且越朝上的区域越亮"。拆解:边缘信息用菲涅尔链(点积、取反、幂);朝上信息用法线与向上向量点积后 Saturate;两路信息要同时满足,用 Multiply 相乘(都大才大)。三段链九个节点,先在纸上把每一环的输出范围写出来,再进图验证。这道题的完整链路会在 5.1 节的练习里以变体形式再次出现——现在做一遍,届时就是复习。

本节要点回顾

  • 先归一化再比较:参与方向比较的向量先过 Normalize,避免长度干扰结果。
  • 点积即接近度:单位向量点积从一到负一,衡量两方向的夹角余弦。
  • 菲涅尔三件套:点积、取反、取幂,五分钟拼出边缘光,是三个案例章的地基。
  • 幂次调形态:边缘光的宽窄由指数控制,把它做成属性随手调。

下一节我们解决"向量在哪个空间"的问题——同样一个方向,切线空间和世界空间里的数值完全不同,空间选错是描边和水面效果翻车的高发原因。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U