返回行业情报

texLab:在UE5内打包PBR贴图而不失真预览

texLab: Packing PBR Maps Inside UE5 Without Lying About the Preview

技术美术Pavel Kuzmenko发布UE5原生C++插件texLab,可在编辑器内直接打包PBR贴图并解包,避免DCC往返流程。工具采用JSON语义数据库定义通道规则,支持浮点处理、BC7/BC5压缩预览及Delta对比,确保预览与输出一致,并提供安全与紧凑两种打包策略及批量验证流程。

深度解读

texLab的核心判断是:纹理打包这个被行业默认为“DCC里做”的环节,其实应该被搬进Unreal Engine内部完成,而且预览必须和最终写盘结果走同一条代码路径——否则你签收的预览和实际资产之间迟早会出现偏差。

这个判断来自Pavel Kuzmenko,一位有feature animation和游戏开发经验的技术美术兼工具开发者。他的出发点非常具体:技术美术在Unreal之外反复重打包纹理所浪费的时间。典型流程是导出单张map、打开另一个DCC、决定通道布局、打包、重新导入、再回Unreal里检查——而此时磁盘上的纹理可能已经和你之前批准的预览不一致了。然后下一个文件夹重复同样的操作。texLab要消灭的就是这个round-trip。

为什么“语义”比“文件名猜测”重要

纹理打包最容易引入的静默生产bug就是通道顺序搞错。ORMRMAARMMSR这些后缀看起来相似,但包含的数据完全不同。文件名启发式看起来很方便,但把Metallic塞进Roughness通道的后果可能要到管线很后期才被发现。

texLab的解法是用显式语义规则取代文件名猜测。规则定义每张源map或打包布局实际包含什么,比如`R = AO, G = Roughness, B = Metallic`。如果遇到未知的打包后缀,工具会报告歧义而不是试图猜测含义。语义数据库基于JSON,这意味着管线TD可以在不修改插件本身的情况下扩展或调整规则。

如果工具无法判断一张打包纹理是ORM还是RMA,我宁愿它停下来报告歧义,也不要悄悄做出错误假设。

这个设计决策的深层含义是:纹理打包工具的可扩展性不应该由插件开发者垄断。每个工作室的命名习惯和管线约定不同,把语义规则外置到JSON,等于把“什么是对的”这个判断权交还给最了解自己管线的人。

一条Pack Graph,没有分叉的预览和导出路径

Manual、Preview、Batch三个工作流共用同一套打包实现——没有各自独立的管线。散图打包、已有打包纹理的解包和重打包,全部走同一个底层处理管线。Preview、Create Outputs、Batch Execute也共用同一个executor。

Kuzmenko刻意避免了单独的assembly路径,原因很直接:如果Preview和Export走不同的代码路径,它们迟早会产生分歧。分歧的后果就是艺术家批准的东西和最终写进磁盘的东西不是同一个东西。

你预览的就是最终被写出来的。

这句话听起来像常识,但在实际生产工具中,预览和导出分属不同模块、各自演化的情况非常普遍。texLab把这个一致性当作架构约束而不是事后验证。

预览本身就是输出的一部分

一个理想化的、未压缩图像的预览在生产中没有太大用处——如果最终资产在BC压缩后看起来会不一样的话。texLab因此提供同一处理结果的多个视图:

- Working — 浮点处理结果 - Encoded — 经过BC7/BC5压缩round-trip后的结果 - Delta — Working和Encoded之间的差异 - Split Channels — 每个通道的实际内容

Encoded预览走的是和输出相同的一般编码路径:工作图像转为合适的8-bit格式、填充到4×4块、通过Unreal Engine的ITextureCompressorModule、按选定recipe压缩。支持的压缩路径包括BC7BC5AutoDXT。压缩结果再解码回float用于显示。

这不是要逐bit复现最终cook后的平台资产——Unreal的cooker和平台特定处理会引入额外差异。它给艺术家的是一个更有用的参考:他们实际签收的那种压缩损失。

浮点管线与有序的标量操作

texLab在整个处理管线中保持图像数据为浮点。它不早早把所有东西转成FColor,而是用FImage/FImageView处理,保持浮点直到导出。转8-bit和块压缩只在输出实际写入时发生。

标量操作在线性空间执行,且始终遵循同一顺序:Gloss → Roughness(需要时)、Invert、Input levels、Midtone adjustment、Contrast、Output levels。比如对比度围绕0.5应用:`t = saturate((t − 0.5) × Contrast + 0.5)`,最终结果再映射到请求的输出范围。

法线重建走同样的思路。DirectX打包的XY值先从[0,1]转到有符号空间,Z从半球重建:`X,Y = 2 × packed − 1`,`Z = sqrt(max(0, 1 − X² − Y²))`。OpenGL来源则在重建前翻转Y。Manual、Preview、Export全部走这同一个有序处理栈。

Safe与Compact:把trade-off摆到台面上

texLab把打包策略分成两大类。Safe策略尽可能保持通道独立,比如`ORM → BC7`、`Normal → BC5`。Compact策略把更多信息塞进更少的纹理资源,帮助减少纹理采样和流送开销。比较激进的布局之一是`GRAH`和`NMG`。

Kuzmenko特别强调:Compact不是隐藏的“Fast”或低质量预设。它是纹理资源、采样和压缩之间的trade-off。UI把这个trade-off显式化,Encoded预览让艺术家在创建最终资产前就能评估压缩结果。随附的Gold Quick Start从`ORM + N [Safe]`开始,让第一个工作流聚焦核心打包过程,不立即引入更激进的策略。

Batch的“dry run”不是装饰

单张纹理的流程很直接:Sources → Channel Assignment → Preview → Create Outputs。文件夹则是:Scan → Rebuild Groups → Validate → Execute。

Validate是真正的dry run。它检查语义覆盖、名称、分组、预估节省量、计划输出的文件——不写任何东西到磁盘。Content Browser在Execute运行前保持不变。

这个设计的意义在于:批量操作最危险的不是速度慢,而是静默地写出一堆错误的文件。把验证做成一个不产生副作用的独立阶段,等于强制在“决定做什么”和“实际做什么”之间加了一道确认门槛。对于管线TD来说,这意味着批量处理的错误可以在写盘之前被拦截,而不是在资产已经进入引擎之后才发现通道搞反了。

这对行业意味着什么

texLab瞄准的是一个长期被忽视的缝隙:DCC功能和资产包之间的地带。大多数纹理工具要么是DCC的内置功能,要么是预打包的资产集合。texLab试图成为第三种东西——一个把DCC纹理打包中有用部分带入Unreal的管线工具,同时不把Unreal变成另一个DCC。

对从业者来说,最直接的信号是:纹理打包的“预览可信度”问题被正式提出来了。当预览和导出走不同代码路径时,艺术家批准的是一种东西,管线产出的是另一种东西,而发现差异的时间点往往晚到无法低成本修复。texLab用单一Pack Graph、浮点管线、Encoded预览和dry-run验证把这几个环节锁在一起,本质上是在说:纹理打包工具的正确性标准不应该低于渲染管线本身。

对管线TD来说,JSON语义数据库的外置意味着他们可以在不碰C++的情况下适配工作室的命名约定和通道布局。对技术美术来说,Encoded预览和Delta视图提供了签收压缩损失的实际依据,而不是靠猜。对工具开发者来说,这个项目的架构选择——单一执行路径、浮点直到导出、验证与执行分离——是可以直接借鉴的模式,无论他们是否在做纹理工具。

软件技术Unreal EnginePBR贴图技术美术工具开发纹理压缩