这一篇要回答的问题:拉丝金属、头发、丝绸的高光为什么会被拉长?答案藏在肉眼看不见的表面结构里。
本文把这条因果链拆开讲清楚:
微观结构 → 微小斜面的朝向分布 → 反射光的分布 → 我们看到的高光形状
读完后,你应该能做到:看到一种材质,推断它的微观结构;看到微观结构,推断它的高光长什么样。
一、核心结论先放在这里
| 层次 | 内容 |
|---|---|
| 原因 | 表面在微观尺度上有带方向的结构:细槽、纤维、发丝、鳞片 |
| 中间环节 | 这些结构让表面上无数微小斜面的朝向分布变成了“椭圆”,而不是“圆” |
| 结果 | 反射光在一个方向上散得开、另一个方向上散不开,高光被拉长 |
| 规律 | 斜面朝向在哪个方向上变化大,高光就往哪个方向拉长 →高光带与纹路垂直 |
一句话:
高光的形状,就是表面微小斜面朝向分布的形状。微观结构有方向,朝向分布就有方向,高光就有方向。
二、什么叫“微观”:尺度决定一切
同一个表面结构,在不同的观察距离下,对画面的影响完全不同。
| 尺度 | 大小 | 例子 | 肉眼 / 画面中的表现 | 渲染中的处理 |
|---|---|---|---|---|
| 宏观 | 厘米以上 | 物体的整体形状、褶皱 | 直接看到形状 | 模型几何 |
| 中观 | 毫米级 | 粗糙的锤纹、明显的刻痕 | 能看到一条条纹路 | 法线贴图 |
| 微观 | 微米级(千分之一毫米) | 拉丝细槽、发丝表面鳞片、纤维 | 看不到纹路本身,只能看到它造成的光效 | 粗糙度、各向异性参数 |
| 波长级 | 约 0.4~0.7 微米 | CD 的光道、蝴蝶翅膀鳞片、肥皂泡 | 彩虹色 | 衍射、薄膜干涉(不属于本文) |
关键在于第三行:
微观结构小到你看不见它,但你能看见它对光的影响。
拉丝不锈钢上的细槽,宽度只有几微米到几十微米。站在一米外,你看不清任何一条槽,但你能清楚地看到那条被拉长的光带。光带就是细槽留下的“签名”。
三、微表面理论:把表面想象成无数面小镜子
1. 基本假设
现代渲染(包括 PBR)对“粗糙表面”的理解是:
任何表面,放大到足够小,都是由无数面极小的平面镜组成的。每面小镜子都严格按照“入射角 = 反射角”反射光线。
宏观上看到的“粗糙”“光滑”,只是这些小镜子朝向是否整齐。
放大前:一块看起来平整的表面 ──────────────────────────── 放大后:无数面朝向各异的小镜子 ╱‾╲_╱‾‾╲╱╲_╱‾╲__╱╲╱‾‾╲_╱╲2. 一面小镜子什么时候“亮”
灯在某个方向,眼睛在另一个方向。一面小镜子要把灯光反射进眼睛,它的朝向必须正好在灯和眼睛的“正中间”。这个正中间的方向,就是渲染中常说的半角向量 H。
灯 眼睛 ╲ H ╱ ╲ ↑ ╱ ╲ │ ╱ ────▔▔▔▔▔──── ← 只有朝向 H 的小镜子,才能把灯光反射进眼睛所以,一个像素有多亮,取决于这个像素范围内“朝向接近 H 的小镜子”有多少。
3. 法线分布:小镜子朝向的“统计图”
一个屏幕像素覆盖的表面区域里,可能有成千上万面小镜子。我们不可能逐个计算,而是统计它们的朝向分布。这就是 PBR 中的法线分布函数(NDF,Normal Distribution Function),也就是公式里那个D 项。
接下来是本文最关键的一个工具。
四、关键工具:法线落点图
1. 怎么画
想象从正上方俯视表面。把每一面小镜子的法线(朝向)想象成一根小棍,从棍子顶端往下投影到一个圆盘上,记一个点:
- 小镜子正好朝上 → 点落在圆盘中心;
- 小镜子向右倾斜 → 点落在中心右边;
- 倾斜越厉害 → 点离中心越远。
把一个像素里所有小镜子的点都画上去,就得到一张“法线落点图”。
2. 三种表面的落点图
① 抛光金属 ② 磨砂 / 喷砂金属 ③ 拉丝金属(细槽沿左右方向) (小镜子几乎都朝上) (小镜子朝向很乱) (只在上下方向上乱) ┌───────────┐ ┌───────────┐ ┌───────────┐ │ │ │ · · · │ │ · │ │ │ │ · ·· ·· · │ │ · │ │ ⁘ │ │ ·· ·⁘· ·· │ │ ⁘ │ │ │ │ · ·· ·· · │ │ · │ │ │ │ · · · │ │ · │ └───────────┘ └───────────┘ └───────────┘ 一小团,圆形 一大团,圆形 一条竖线(细长椭圆)3. 落点图 = 高光的形状
现在把灯光和视角考虑进来:只有朝向接近 H 的小镜子才亮。当你移动灯光或视角,H 在落点图上移动——H 扫过点密集的区域时就亮,扫过空白区域时就暗。
所以落点图在哪个方向上铺得开,高光就在哪个方向上“够得着”:
| 落点图 | 高光 | 材质 |
|---|---|---|
| 一小团圆形 | 小而亮的圆点 | 抛光金属、汽车漆 |
| 一大团圆形 | 大而模糊的圆斑 | 磨砂金属 |
| 竖向细长 | 竖向拉长的光带 | 拉丝金属(细槽横向) |
这就是“微观结构造就各向异性光效”的全部机制:
微观结构 → 决定落点图的形状 → 落点图的形状就是高光的形状。落点图是圆的 → 各向同性;落点图是椭圆的 → 各向异性。
五、为什么拉丝细槽让落点图变成竖线
这是理解“高光与纹路垂直”的关键一步。
拉丝金属的细槽沿左右方向延伸。分别看两个方向的剖面:
沿槽方向(左右)剖开: ───────────────────────────── 一条直线。沿这个方向,小镜子没有左右倾斜 → 落点图在“左右”方向上没有展开 垂直槽方向(上下)剖开: ⌒⌒⌒⌒⌒⌒⌒⌒⌒⌒⌒⌒⌒⌒⌒⌒⌒ 一个个小圆弧。每个圆弧上,小镜子从“向上倾”到“向下倾”都有 → 落点图在“上下”方向上铺得很开结论:
细槽方向:左右 → 斜面在“上下”方向倾斜 → 落点图上下展开 → 高光上下拉长纹路本身不倾斜,横穿纹路的方向才倾斜。所以高光总是沿垂直于纹路的方向被拉开。
六、案例逐个拆解:从微观结构推出光效
下面每个案例都按同一个格式分析:微观结构 → 落点图 → 光效。
案例 1:抛光金属(各向同性,作为对照)
| 环节 | 内容 |
|---|---|
| 加工方式 | 用越来越细的抛光膏在各个方向上反复打磨 |
| 微观结构 | 极小的随机起伏,没有方向 |
| 落点图 | 中心一小团,圆形 |
| 光效 | 小而亮的圆形高光 |
案例 2:喷砂 / 磨砂金属(各向同性)
| 环节 | 内容 |
|---|---|
| 加工方式 | 用高压喷射砂粒撞击表面 |
| 微观结构 | 无数随机的小坑,坑壁朝向各个方向 |
| 落点图 | 一大团,圆形 |
| 光效 | 大而柔和的圆斑,质感“哑光” |
案例 1 和 2 说明:粗糙程度只决定落点图的大小,不决定形状。加工没有方向,落点图就是圆的。
案例 3:拉丝金属(直线各向异性)
| 环节 | 内容 |
|---|---|
| 加工方式 | 砂带或砂纸只沿一个方向反复打磨 |
| 微观结构 | 平行的细槽,深度和宽度通常在微米级 |
| 落点图 | 垂直于细槽方向的细长椭圆 |
| 光效 | 垂直于拉丝方向的光带 |
推论:打磨越用力、砂纸越粗,细槽越深,槽壁越陡 → 落点图越长 → 光带越长。
案例 4:车削金属、锅底(局部方向变化)
| 环节 | 内容 |
|---|---|
| 加工方式 | 工件旋转,刀具固定切削(车床),或旋转抛光 |
| 微观结构 | 一圈圈同心圆细槽 |
| 落点图 | 每个位置都不一样:每一点的细槽沿圆周方向,落点图就沿该点的半径方向拉长 |
| 光效 | 从圆心向外放射的光带,移动灯光时像指针一样转动 |
每个位置的落点图方向(沿半径): │ ╲ │ ╱ ╲ │ ╱ ───────◯─────── ╱ │ ╲ ╱ │ ╲ │为什么光带是放射状的:只有某些位置的椭圆正好对准当前的 H,这些位置连起来,正好是一条穿过圆心的线。
这个案例说明:各向异性的方向可以逐点变化。渲染中需要逐像素提供纹路方向,这就是“方向贴图(Tangent Map / Flow Map)”的用途。
案例 5:手表太阳纹(与案例 4 相反)
| 环节 | 内容 |
|---|---|
| 微观结构 | 从中心向外放射的细槽 |
| 落点图 | 每个位置沿圆周方向拉长 |
| 光效 | 环形或弧形的光 |
对比案例 4:纹路是圆的,高光就是放射的;纹路是放射的,高光就是圆的。永远垂直。
案例 6:头发(圆柱 + 鳞片)
头发是各向异性最典型、也最复杂的例子,它的微观结构有两层。
第一层:发丝是细圆柱
一根头发直径约 0.05~0.1 毫米。圆柱的侧面朝向绕着发丝转一整圈。
一根竖直发丝的横截面(俯视): ↑ ↖ ↗ ← ● → 侧面朝向覆盖了“水平方向”的一整圈 ↙ ↘ ↓| 环节 | 内容 |
|---|---|
| 落点图 | 沿垂直于发丝的方向铺成一整条线(比拉丝金属更极端) |
| 光效 | 整头竖直的发丝,在同一高度上连成一圈横向光环——天使环 |
第二层:发丝表面的鳞片
在电子显微镜下,头发表面覆盖着像屋顶瓦片一样层层叠叠的角质鳞片(Cuticle),鳞片的边缘朝向发梢,相对发丝轴线倾斜约 3°。
放大的发丝侧面(发根在左,发梢在右): ╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱ 鳞片像瓦片一样,微微倾斜这个微小的倾斜,加上光可以进入发丝内部,造成了两条高光:
| 高光 | 光的路径 | 表现 |
|---|---|---|
| 主高光 | 在鳞片表面直接反射 | 偏白,较窄 |
| 次高光 | 进入发丝、在内部背面反射、再射出 | 被发丝内部的色素“染色”,带发色,较宽、较散 |
由于鳞片的倾斜,两条高光沿发丝方向朝相反方向错开一点。这就是写实头发中常见的“上白下彩”的双层高光,也是 Marschner 模型的物理依据。
渲染中的“切线偏移(Shift Tangent)”参数,模拟的就是鳞片倾角造成的高光位置偏移。偏移贴图加噪声,模拟的是每根头发鳞片和走向的细微差异。
推论:
- 头发受损、鳞片翘起 → 表面变乱 → 天使环变弱,头发“发干无光泽”(这正是洗发水广告追求天使环的原因);
- 卷发、乱发 → 发丝方向杂乱 → 局部的落点图方向各不相同 → 光环碎成零散的亮点。
案例 7:丝绸、缎面(纤维 + 编织方式)
| 环节 | 内容 |
|---|---|
| 微观结构 | 蚕丝纤维光滑且横截面接近三角形;缎纹织法让一个方向的纱线在表面长距离漂浮(一根纱线跨过好几根纱线才下沉一次) |
| 落点图 | 表面以单一方向的长纤维为主,落点图明显拉长 |
| 光效 | 强烈、流动的光泽,随褶皱变化 |
对比实验:同样是丝,不同织法的光效差异很大:
| 织法 | 表面纤维方向 | 光效 |
|---|---|---|
| 缎纹 | 一个方向占绝对主导 | 光泽最强,各向异性最明显 |
| 斜纹 | 两个方向都有,一个略多 | 有光泽,带斜向纹理感 |
| 平纹 | 两个方向均匀交错 | 光泽柔和,接近各向同性 |
这个案例说明:决定光效的不只是材料本身,还有材料的排列方式。同样的蚕丝,排列有方向,光效就有方向。
案例 8:虎眼石、猫眼石(内部结构)
前面的例子都是表面结构。这个例子说明内部结构同样有效。
| 环节 | 内容 |
|---|---|
| 微观结构 | 宝石内部含有大量平行排列的纤维状或针状包裹体 |
| 原理 | 每根细纤维都像一根细圆柱,和头发一样把光反射成垂直于纤维的一条线 |
| 光效 | 打磨成弧面后,表面出现一条垂直于纤维方向的亮线,转动宝石时亮线会移动,像猫的瞳孔——称为“猫眼效应”(Chatoyancy) |
案例 9:木纹(透过清漆的各向异性)
| 环节 | 内容 |
|---|---|
| 微观结构 | 木材由平行的纤维管组成,表面刷了透明清漆 |
| 光效 | 清漆表面有一个普通的圆形高光;清漆下方的木纤维还会产生一层沿纹理拉长的、随角度移动的光泽 |
一些名贵木材(如带“虎纹”“琴背纹”的木材)在转动时会出现明暗交替的流动光泽,原因就是纤维方向在局部起伏变化。
案例汇总
| 材质 | 微观结构 | 结构方向 | 高光形状 |
|---|---|---|---|
| 抛光金属 | 随机微小起伏 | 无 | 小圆点 |
| 磨砂金属 | 随机小坑 | 无 | 大圆斑 |
| 拉丝金属 | 平行细槽 | 直线 | 垂直于拉丝的光带 |
| 车削金属 | 同心圆细槽 | 圆周 | 放射状光带 |
| 太阳纹表盘 | 放射细槽 | 半径 | 环形光 |
| 头发 | 细圆柱 + 倾斜鳞片 | 沿发丝 | 横向光环,双层错开 |
| 缎面 | 单向漂浮的长纤维 | 沿经线或纬线 | 流动光泽 |
| 虎眼石 | 内部平行纤维 | 沿纤维 | 垂直于纤维的亮线 |
| 木材 | 纤维管 | 沿木纹 | 漆下拉长的光泽 |
七、尺度的转换:同一个结构,远近不同
这一点对渲染特别重要。
1. 拉近与拉远
想象用放大镜从远到近观察一块拉丝金属:
| 观察距离 | 一个像素覆盖的范围 | 看到什么 | 渲染中应该怎么表达 |
|---|---|---|---|
| 极近(微距) | 小于一条槽 | 一条条清楚的细槽,每条槽有自己的高光 | 几何或法线贴图 |
| 中等 | 几条槽 | 隐约可见的纹理 + 拉长的光带 | 法线贴图 + 各向异性 |
| 正常距离 | 成百上千条槽 | 看不到槽,只有光滑的拉长光带 | 只用各向异性粗糙度 |
当结构小到一个像素装得下很多个时,它就从“看得见的形状”变成了“看不见的材质属性”。各向异性粗糙度,本质上是对“一个像素内无数细槽”的统计描述。
2. 一个工程上的重要推论:法线贴图远处会“变成”各向异性
如果一张法线贴图上画着平行的细槽,近处它表现为一条条槽;拉远后,贴图的 Mipmap 会把很多条槽平均成一个朝上的法线,于是:
- 槽的细节消失了(这是对的);
- 但槽造成的各向异性光带也一起消失了(这是错的)——远处的拉丝金属突然变成抛光金属,看起来闪亮、发假。
正确的做法是:法线贴图在降低分辨率时,把丢掉的法线变化转换成粗糙度——如果丢掉的变化有方向,就转换成各向异性粗糙度。这类技术包括 Toksvig 方法、LEAN Mapping(Olano 与 Baker,2010)等,其中 LEAN Mapping 能直接保留各向异性。
这再一次印证了本文的主题:中观的法线贴图拉远之后,就成了微观结构;微观结构的统计,就是粗糙度和各向异性。
八、一个验证实验:不写各向异性公式,也能得到各向异性高光
如果“微观结构造就各向异性”是对的,那么只要真的在一个像素里模拟一堆细槽,不用任何各向异性公式,也应该能得到拉长的光带。
下面的示意 Shader 就做了这件事:在一个像素内多次采样,每次用一个按细槽形状扰动的法线计算普通的各向同性Blinn-Phong 高光,最后取平均。
// 示意:用"暴力模拟细槽"验证各向异性的来源 // 注意:这里的高光公式本身是各向同性的 Blinn-Phong float GrooveSpecular(float3 N, float3 T, float3 B, float3 H, float grooveSlope, float shininess) { const int SAMPLES = 16; float sum = 0.0; for (int i = 0; i < SAMPLES; i++) { // 在一条细槽的横截面上取不同位置:从 -1 到 1 float s = (i + 0.5) / SAMPLES * 2.0 - 1.0; // 细槽横截面是圆弧:法线只在 B 方向(垂直于槽)上倾斜, // 在 T 方向(沿槽)上完全不倾斜 float3 microN = normalize(N + B * (s * grooveSlope)); // 每面小镜子都用普通的各向同性高光 sum += pow(saturate(dot(microN, H)), shininess); } return sum / SAMPLES; }| 参数 | 结果 |
|---|---|
grooveSlope = 0 | 所有小镜子朝上,退化为普通圆形高光 |
grooveSlope增大 | 高光沿 B 方向(垂直于槽)被拉长 |
把扰动方向从B改成T | 光带旋转 90° |
每一面小镜子都是普通的、各向同性的;但它们的朝向分布有方向,整体就变成了各向异性。
这正是本文标题的意思。实际项目中不会这样暴力采样(太贵),而是用各向异性 GGX、Kajiya-Kay 这类解析模型直接给出“一堆有方向的小镜子平均后的结果”。
九、对应到渲染参数
理解了微观结构,各向异性模型里的每个参数都有了物理含义:
| 微观结构的属性 | 渲染参数 | 说明 |
|---|---|---|
| 纹路朝哪个方向 | 切线 T / 副切线 B、方向贴图 | 来自 UV 展开或单独的方向贴图 |
| 沿纹路方向有多平整 | 沿 T 的粗糙度 αt | 越平整越小 |
| 横穿纹路方向的坡度 | 沿 B 的粗糙度 αb | 槽越深、越陡,这个值越大 |
| 两个方向的差异程度 | Anisotropy(各向异性强度) | 引擎把 αt、αb 合成一个美术参数;为 0 时退化为各向同性 |
| 纹路方向逐点变化(车削、太阳纹、发丝走向) | 方向贴图 / Flow Map | 逐像素提供 T 的方向 |
| 头发鳞片的倾角 | 切线偏移(Shift) | 控制高光带沿发丝方向的位置 |
| 每根发丝、每条槽的细微差异 | 偏移噪声贴图、高光遮罩 | 打散高光边缘,避免“塑料感” |
| 光进入纤维内部再射出 | 次高光颜色、宽度 | Marschner 模型中的 TT、TRT 分量;简化模型中用第二层带颜色的高光近似 |
| 整体的光滑程度 | 粗糙度 Roughness | 决定落点图的整体大小 |
调参时,可以先问自己三个问题:
- 纹路朝哪?→ 设置切线方向或方向贴图;
- 整体有多光滑?→ 设置粗糙度;
- 两个方向差别有多大?→ 设置各向异性强度。
十、常见误解
| 误解 | 实际情况 |
|---|---|
| “各向异性是材质的一种特殊属性,和粗糙度无关” | 各向异性就是粗糙度在两个方向上不同。它不是额外的东西,而是粗糙度的“方向版本” |
| “高光带沿着纹路方向” | 恰好相反,高光带垂直于纹路。纹路本身是平的,横穿纹路的方向才有倾斜 |
| “看得见纹路才有各向异性” | 纹路越看不见(越微观),越需要用各向异性参数表达。看得见的纹路反而应该交给法线贴图 |
| “法线贴图画上细槽就够了” | 近处够,远处 Mipmap 会把槽平均掉,各向异性光带随之消失,需要把丢失的法线变化转成(各向异性)粗糙度 |
| “头发只是拉长的高光” | 头发还有光在发丝内部的透射和二次反射,所以写实头发有两层不同颜色的高光,并带有背光透亮效果 |
| “金属才有各向异性” | 头发、毛皮、丝绸、木材、部分宝石都有,只要微观结构有统一方向就会出现 |
| “越强越好” | 现实中多数拉丝金属的各向异性比较克制,参数调得过大,光带会细长得像一条线,显得假 |
十一、实用推论:怎么判断、怎么设置
1. 拿到一种材质,先问它是怎么“做出来”的
| 制造 / 生长方式 | 推断的微观结构 | 是否需要各向异性 |
|---|---|---|
| 铸造、喷砂、腐蚀 | 随机坑点 | 否 |
| 多方向抛光、喷漆、电镀 | 随机微小起伏 | 否 |
| 单方向打磨、拉丝 | 平行细槽 | 是,方向沿 UV 统一 |
| 车床加工、旋转抛光 | 同心圆细槽 | 是,需要绕中心的方向贴图 |
| 生长出来的纤维(头发、毛、蚕丝、木材) | 定向纤维 | 是,方向沿纤维走向 |
| 编织物 | 取决于织法 | 缎面明显,平纹棉布基本不需要 |
加工有方向,材质就有方向。这是判断是否需要各向异性的最快方法。
2. 最好的参考是实物
制作前用手机手电照一照参考物,记录三件事:
| 观察项 | 对应参数 |
|---|---|
| 光带朝哪个方向 | 切线方向(与光带垂直的就是纹路方向) |
| 光带有多长、多宽 | 各向异性强度、粗糙度 |
| 旋转物体时光带是否跟着转 | 确认确实是各向异性,而不是掠射角造成的拉长 |
3. 程序侧的检查要点
- 提供切线方向调试视图,把 T 以颜色显示,美术一眼就能看出 UV 方向是否统一;
- 头发、拉丝零件导入时不要重算切线,并确认 DCC 与引擎使用同一切线算法;
- 远景测试:把镜头拉远,检查光带是否突然消失或开始闪烁;
- 移动端:只在近景、关键物体(主角头发、主要武器)上启用各向异性。
小结
整条因果链:
加工或生长方式有方向(打磨、车削、发丝生长、纺织) │ ▼ 微观结构有方向(细槽、纤维、圆柱、鳞片) │ ▼ 微小斜面只在“横穿纹路”的方向上倾斜 │ ▼ 法线落点图从“圆”变成“椭圆” │ ▼ 反射光一个方向散开、另一个方向集中 │ ▼ 高光被拉成光带或光环,且与纹路垂直 —— 各向异性光效| 要点 | 内容 |
|---|---|
| 根本原因 | 微观结构有方向 |
| 核心机制 | 小镜子的朝向分布(法线分布)变成椭圆 |
| 核心规律 | 高光形状 = 法线分布的形状;高光带垂直于纹路 |
| 尺度关系 | 看得见的纹路用法线贴图;看不见的纹路用各向异性粗糙度;两者之间要正确衔接 |
| 渲染对应 | 切线方向 + 两个方向的粗糙度;头发再加鳞片偏移与内部透射 |
一句话概括:每一面小镜子都是普通的,但当它们按某个方向排列时,整体就有了方向——各向异性光效不是光的特殊行为,而是微观结构排列方式在光上的投影。
参考资料
- R. L. Cook, K. E. Torrance:《A Reflectance Model for Computer Graphics》,ACM TOG 1982(微表面模型的经典起点)
- Bruce Walter 等:《Microfacet Models for Refraction through Rough Surfaces》,EGSR 2007(GGX 分布)
- Eric Heitz:《Understanding the Masking-Shadowing Function in Microfacet-Based BRDFs》,JCGT 2014
- Gregory J. Ward:《Measuring and Modeling Anisotropic Reflection》,SIGGRAPH 1992
- J. T. Kajiya, T. L. Kay:《Rendering Fur with Three Dimensional Textures》,SIGGRAPH 1989
- Stephen R. Marschner 等:《Light Scattering from Human Hair Fibers》,SIGGRAPH 2003
- Michael Toksvig:《Mipmapping Normal Maps》,2005
- Marc Olano, Dan Baker:《LEAN Mapping》,I3D 2010
- Google Filament:Physically Based Rendering in Filament(各向异性章节)
延伸阅读
- 《渲染入门|各向异性高光:用生活中的例子讲清楚》
- 《渲染入门|各向异性高光:拉丝金属、头发与丝绸的光泽》
- 《渲染入门|从 Lambert 到 PBR:光照模型的演进》
- 《渲染进阶|法线贴图的 Mipmap 问题:Toksvig、LEAN 与粗糙度修正》