4.3 纹理进阶:2D vs 立方体 vs PBR 本节摘要:二维纹理按 UV 采样,是表面细节的通货。立方体贴图按方向采样,用来做环境反射与天空。PBR 工作流把反照率、法线、金属度、粗糙度、环境光遮蔽拆成多张 2D,再加一张预滤波立方体做 IBL。通道越多,CPU 上传与 GPU 带宽越重。选型应按阶段:先一张固有色,再加法线,最后才是完整金属粗糙度,而不是第一天就开齐五个采样器。
本节摘要:二维纹理按 UV 采样,是表面细节的通货。立方体贴图按方向采样,用来做环境反射与天空。PBR 工作流把反照率、法线、金属度、粗糙度、环境光遮蔽拆成多张 2D,再加一张预滤波立方体做 IBL。通道越多,CPU 上传与 GPU 带宽越重。选型应按阶段:先一张固有色,再加法线,最后才是完整金属粗糙度,而不是第一天就开齐五个采样器。
阅读完本节,你应当能够:
2D 纹理的坐标是网格自带的 UV,CPU 组装进 Attribute。立方体的坐标是世界或观察空间的方向向量,常在 FS 用反射向量去采。把 UV 拿去采立方体,或把反射向量当 2D UV,会得到无法辨认的接缝。三维纹理用体积坐标,体数据可视化才需要,WebGL2 核心更完整。
天空盒是立方体的特例:用顶点位置当方向,关掉平移,深度放很远。环境反射是同一张或同一组立方体,在物体 FS 里按反射采。CPU 上传六张面或压缩的立方体;GPU 按三维方向滤波。过滤合同仍适用:无 mip 的环境在粗糙表面上会闪。
2D: UV Attribute → 表面细节 立方体: 方向向量 → 环境、天空、IBL 镜面 3D: 体积坐标 → 雾、体数据
| 槽 | 空间 | 过滤 | 缺了怎么办 |
|---|---|---|---|
| 反照率 | sRGB | mip 线性 | 用 Uniform 固有色 |
| 法线 | 线性,勿当照片乱压 | mip 要小心,或限制级数 | 用几何法线,回到光滑 |
| 金属度 | 线性标量 | 可与粗糙打包 | 当电介质,金属度 0 |
| 粗糙度 | 线性标量 | 同上 | 固定 0.5 |
| AO | 线性 | 可打包 | 常数 1 |
| 环境立方体 | 按工作流 | mip 对应粗糙 | 常数环境色 |
切线空间法线贴图:FS 要把贴图里的法线转到世界。需要切线、副切、几何法线组成 TBN。切线常由 CPU 在导入时算,进 Attribute。没有切线就用法线贴图,方向会随 UV 扭曲乱转。引擎导入 glTF 时自动带 TBN;裸写自己解析时这是坑。
vec3 nTex = texture2D(uNormal, vUv).xyz * 2.0 - 1.0; vec3 n = normalize(TBN * nTex);
PBR 镜面项要用粗糙度选环境立方体的 mip 级别:光滑采高层细节,粗糙采模糊层。CPU 必须生成或加载预滤波 mip。只丢一张未滤波天空进镜面,金属会像贴了张高对比壁纸。这是资产管线合同,不是 FS 一行 pow 能代替。

ORM 打包:遮蔽、粗糙、金属放进一张图的三个通道,一次采样。CPU 资产要约定通道顺序,引擎 glTF 有惯例。乱打包会让金属变粗糙。移动端这是减单元占用的首选,比“砍掉法线”更值得。
立方体尺寸 256 往往够环境,2048 是给天空背景。同一套资产两份分辨率。压缩格式按平台回退,第 2.6 节那张矩阵在立方体上同样成立,只是份数乘六或用专用立方体压缩。
⚠️ 常见坑:法线贴图当 sRGB 解码,凹凸发紫或方向错。数据贴图走线性。颜色空间跟槽走,不跟“是不是图片”走。
💡 关键直觉:每加一个采样器,先问屏幕上能否看出差异。看不出,就不要加。PBR 清单不是开学必买文具。
程序化纹理:CPU 画 canvas 再上传,或 GPU 用 FS 生成噪声。噪声每帧生成是 GPU 税;一次生成进纹理是缓存。木纹、棋盘教学可用程序化;产品材质仍以资产为准。不要在生产 FS 里用一长串 sin 冒充大理石还当 PBR。
能做公式,看起来像塑料球。PBR 的观感一半在贴图。缺贴图时用程序化值加一张 IBL,比乱填噪声图更诚实。等有 glTF 再填槽。引擎的默认球就是这个阶段。把它当最终品质会失望,把它当着色器是否跑通的探针刚刚好。
镜像 UV 的网格,切线场容易反,法线贴图的凹凸左右颠倒。导入时检测 UV 面积符号,翻转切线。运行时发现“凹凸是凹的”,先查切线再查法线贴图是否重复压缩成 sRGB。两次错误会互相抵消成“看起来还行”,第三次改资产又全坏。只修一层,把抵消拆开。调试输出 TBN 的三个轴当颜色,比盯最终光照快。
环境预滤波:离线工具把立方体生成 mip,每层对应粗糙度。运行时按粗糙度选 lod。没有离线工具时,可在加载期用离屏对立方体做几次模糊写入 mip,那是 CPU 调度多次 GPU pass,启动更慢。查看器可接受三秒预热;游戏关卡加载条要算进去。不要每帧预滤波。预滤波是资产,不是效果开关。
视差遮挡、清漆层、各向异性高光,都是在 PBR 槽齐了之后的加料。加料前问屏幕占比。鞋子在商品页占 400 像素宽,视差可能值;缩略图 64 像素,视差等于噪声。效果路线按屏幕覆盖裁剪,与 2.6 的 4K 贴图问题同一把尺。
立方体动态更新:要反射周围动态物体,得每帧或每几帧从六个方向离屏画到立方体。六次场景绘制,CPU/GPU 税巨大。产品查看器通常用静态工作室环境。游戏里只给近处重要物体低频更新,或用屏幕空间反射代替。动态立方体不是“反射开关”,是六份视口。
PBR 多槽若打进同一图集,WRAP 与 mip 渗色会让金属度在边缘闪。ORM 可以打包,但不要和反照率图集混同一张重复平铺的砖。平铺砖单独 REPEAT。流式 mip:先上传低层尽快显示,高层后台补。CPU 管理层索引。引擎有时支持;裸写要注意 generateMipmap 会覆盖你手工层。手工流式就不要 generate。合同一次只选一种生成者。
切线场与镜像 UV。导入修切线。法线贴图绿通道约定也要与引擎一致。直接在 FS 里翻转切线可以应急。资产规范写明,避免每套模型现场翻。调试输出切线轴颜色。
环境没有按粗糙度预滤波,或 lod 没连上。光滑应看到清晰环境,粗糙应糊。全是同一清晰度就是 mip 合同没建。加载期滤波或离线打链。不要用 pow 冒充滤波。
ORM 打包、减槽、合并。移动上限比桌面紧。PBR 全槽加阴影加 IBL 加后处理输入,单元会超。超了绑定静默错乱,材质串味。串味先数单元,再怀疑着色器。
材质槽位表:反照率、法线、ORM、发光、环境。每槽颜色空间、缺省值、是否可选。加载按表填,缺可选槽用缺省。缺必选槽用粉占位。预滤波立方体构建期生成,运行时当资产。加载期滤波只给编辑器。动态立方体默认关,开了要限频率与物体白名单。切线导入失败拒绝网格,不要静默用法线贴图。拒绝信息写进加载日志。槽位超了优先 ORM 打包,再减发光,再减 IBL 分辨率。减的顺序写进表,避免现场吵架。
PBR 槽位按阶段开。第一周只有反照率的查看器是合格的。加法线要有切线,切线失败拒绝。加 ORM 要线性。加 IBL 要预滤波链。四步每步可停。停在第三步的产品仍然成立。动态立方体默认关,白名单空。打开要有频率,例如每十帧更新近处一个探针。没有频率等于六倍场景绘制。图集不放平铺砖。单元超限测试用最低端档位机。超了按表减槽:发光先走,IBL 降尺寸,再 ORM 已打包则减法线。减法线比黑屏好。串味时数 activeTexture,不要先改 GGX。GGX 不负责绑错单元。
阶段开槽写成加载器策略:缺切线则拒绝法线槽;缺预滤波则拒绝镜面 IBL,退回半球。拒绝要日志。静默用错槽比拒绝更糟,因为画面“还能看”,债会堆。堆到单元超限才爆串味。串味时已经难拆。策略把爆点提前到加载,加载失败比运行串味好修。
现场对照时只改一个变量。同时改版本、封装、通道,归因会消失。消失之后只能靠感觉,感觉正是本书要拆掉的东西。把改动写成一条,测完再写下一条。一条一条,四组对照才用得上。用不上的对照表只是装饰。装饰填不满格子,格子空着就不要标完工。纹理槽这一格改完,确认切线与预滤波,不要一次开齐五槽。
下一节对照动画:物体级运动改矩阵,皮肤级变形把账交给 GPU 还是每帧改 VBO。