2D游戏法线贴图程序化生成工作流:五分钟从平涂到动态受光

发布时间:2026/9/15 4:36:31
2D游戏法线贴图程序化生成工作流:五分钟从平涂到动态受光 1. 从一张平涂到动态受光这条工作流到底改变了什么先说我自己的处境。前阵子帮朋友的项目补一批2D道具资源数量不大也就二十来件剑、盾、药水瓶、木箱、卷轴、一小堆杂物。原画早就画完了每一张都是干干净净的平涂带一点二分阴影。然后问题来了——项目要用2D动态光照所有Sprite都需要法线贴图。按传统流程走我打开PS开始手涂法线涂到第三把剑的时候看了一下时间快两个小时过去了。二十多个道具按这个速度光法线就要涂整整两天。而且说句公道话手涂法线这个东西涂得越多越考验耐心后边几张的质量明显不如前几张手一滑还会把不该凸的地方画凸。后来我换了思路把手涂法线改成程序化生成。单张道具从导入工具到最终导出引擎可用的法线贴图算上参数微调最快一张不到五分钟。二十多张图一个下午全部搞定导入Unity之后动态光一扫立体感完全够用。最直观的对比是那两把已经手涂完的剑跟后面程序化生成的剑放在同一个光源下不放大看几乎分不出差别。这不是什么黑科技也谈不上复杂。它本质上就是把手艺人一笔一笔画立体感这件事变成让算法从明暗信息里算立体感。这篇文章我把自己测试过的几条路径、具体参数、踩过的坑全部写出来。如果你也在做2D游戏、做Live2D配件、做UI动态展示或者手里压着一大批等着进引擎的平涂素材这篇文章能帮你省下大量时间。2. 法线贴图里装的不是颜色是方向在开始操作之前我建议先花两分钟搞明白法线贴图到底存了什么。很多人用了很久法线贴图只记得偏蓝偏紫的图贴上去就有立体感但不知道为什么是蓝紫色、为什么生成工具要调那一堆参数。这部分搞懂了后面调参就不会瞎试。2.1 一张偏蓝的图怎么就让光动起来了法线贴图在切线空间里存储的是每个像素表面朝向的向量这个向量的三个分量分别映射到RGB三个通道。在绝大多数引擎的约定里R通道对应切线方向X轴G通道对应副切线方向Y轴B通道对应法线方向Z轴。对于一个正对着摄像机、没有凹凸的平面表面法线应该指向屏幕外也就是Z轴正方向。换算成RGB值就是(128, 128, 255)看起来就是那种很典型的蓝紫色。至于某个地方有个鼓包或者凹陷那个像素的X、Y分量就会偏离128颜色的红绿分量跟着变蓝紫色就不均匀了。我之前跟团队里新来的同学解释这个事用的比喻是法线贴图里存的是一个个小像素的朝向指纹光照计算的时候引擎拿着这枚指纹去算这个像素应该亮还是暗、应该反射哪边的光。所以同样一张原图光源从左边打和从右边打同一个像素会做出完全不同的反应——这就是动态受光的底层来源。2.2 生成算法是怎么凭空算出来立体感的那问题来了法线贴图里的方向信息如果不手涂计算机怎么知道哪里该凸、哪里该凹核心思路不复杂。所有免费生成法线贴图的工具底层都是先建立一张高度图再对高度图做梯度计算。高度图可以理解为一张灰度图越亮表示越高越暗表示越低。平涂原图里明暗交界处其实就藏着高度信息——亮部通常被认为是受光面或者较高区域暗部被认为是背光面或者低洼区域。工具拿到这些相对高度之后会对比相邻像素的高度差。一个像素比左边高、比右边低那这个像素的法线就会向高的一侧倾斜用这个逻辑计算出一个方向向量写入RGB通道。这是所有基于图片明度转法线的通用原理也是最常见的从明度推方向方案。明白了这一点你就知道那些参数在干什么了调强度就是放大或缩小高度差对方向的影响调对比度就是先拉大明暗差距再算梯度调平滑度就是减少噪点造成的假凹凸。所以程序化生成法线本质上不是无中生有而是把画家画在颜色里的光影关系翻译成引擎能读懂的方向关系。3. 工具选型对比实测五款免费方案的优缺点从手涂切到程序化生成第一个要回答的问题就是用什么工具。我前后测试了五款免费方案各有取舍。先放结论做2D游戏Sprite类素材我目前主力用的是Laigter做需要精细控制曲线的单张图我用GIMP的Normalmap插件做PBR场景材质Materialize更顺手。3.1 五款方案的横向对比下表是我实测下来比较关心的几个维度价格、实时预览、批量处理、对透明通道的支持、以及生成质量的控制力。工具平台实时预览批量处理Alpha通道支持参数控制力适合场景LaigterWindows/Linux/开源支持带动态光源预览支持序列帧批量生成支持可基于透明生成高度中等预置项够用2D游戏Sprite、序列帧GIMP Normalmap插件跨平台支持3D预览不支持支持高深度算法多单张精修、需要手动曲线MaterializeWindows支持不支持支持中等偏上PBR材质四件套一键生成NormalMap-Online网页版支持不支持部分支持中等快速出图、临时应急Blender内建图像纹理生成跨平台支持可节点化支持极强但上手门槛高已有Blender工作流的人3.2 不同项目类型的选型建议这里按项目类型给点选型建议都是我自己趟过的经验。如果你的项目是2D横版动作、2D俯视角RPG或者主打动态光照的2D场景我首推Laigter。原因很实在它专门为游戏精灵设计可以直接读取透明底PNG对序列帧有批量处理导出的法线贴图自带边缘处理不会在Sprite边缘留一圈难看的白边。我主力用它就是看中这两个点。如果你的单张素材对立体感要求很高比如主角立绘、重要剧情道具需要精确控制衣服褶皱的走向、金属高光的范围那Laigter预设的参数不够用。这时候GIMP的Normalmap插件更合适它提供多种深度算法还可以手动调整高度图再生成控制力强很多。如果你做的是风格化场景想从一张颜色贴图一键得到一套PBR贴图那Materialize更对口。它能一次输出法线、粗糙度、高度、金属度四张图虽然法线质量跟单独做有差距但对场景里的远景物件完全够用。网页版工具适合什么情况临时想验证一张图生成效果、手边又没有安装环境的时候。我一般不把它作为主力因为批量处理、细节控制都有短板。Blender那条路适合本来就在Blender里搭场景做2.5D的人图像纹理节点法线贴图转换一步到位模型面法线正好可以顺手校对但纯2D项目用不到这么重的工作流。3.3 为什么我最后主力选了Laigter多说一句为什么选Laigter。它的核心逻辑跟我的需求高度匹配输入是一张透明底的2D原画输出是配套的法线贴图高光贴图高度图。它默认把透明区域当作完全平坦的桌面来处理生成的法线只在有像素的区域生效这在2D游戏里太关键了——因为游戏Sprite几乎全是透明底手涂法线的时候最麻烦的恰恰就是边缘的半透明处理工具自动帮你规避了。另外一个隐藏优势是它免费开源格式兼容性好。导出的贴图在Unity、Godot、UE里都能正确识别不会出现某些闭源小工具导出的法线贴图通道顺序跟引擎约定不一致的问题。4. 五分钟从平涂原画到引擎可用法线完整实操记录接下来进入正题我用一张实际的道具原画完整走一遍流程。这张图是一把1024×1024的短剑白背景平涂剑身银灰色、护手棕色、剑柄深色带一层非常简单的阴影没有任何渐变和高光细节。这是很典型的游戏原画给到美术整合环节的状态。4.1 生成法线前原画需要做什么预处理很多人直接拿成品原画丢进工具里生成出来的法线效果很差问题往往出在预处理没做。第一件事是抠图。尽量把主体从背景里分离出来输出透明底PNG。这一步很关键因为背景的明暗信息会被错误识别成高度差生成的法线会带着背景的地形起伏。我用的是PS的快速选择工具加羽化1像素边缘不追求完美但尽量干净。第二件事是检查主体明暗是否清晰。前面讲过生成算法靠明度推高度如果一张平涂图完全没有阴影所有区域亮度一样那算出来的高度场基本是平的出来的法线也几乎没有起伏。我这张短剑好在带一点简单二分阴影工具能从中提取出基本的光影关系。第三件事是尺寸。不强制要求2的幂但建议保持正方形并且尺寸别太小。1024×1024是个很均衡的选择生成速度快细节足够引擎里压缩也方便。建议不要直接拿512以下的小图放很大用法线贴图本身就依赖像素密度源图太小放大了全是锯齿状光斑。4.2 Laigter关键参数逐项拆解打开Laigter把短剑PNG拖进窗口。界面左边是原图右边是3D预览中间一排是参数面板。我按实际修改顺序讲几个最有用的。第一个要动的是Height Source也就是高度来源。默认是Luminosity即用明度作为高度参考。平涂插画选这个没问题。如果你的原图有非常清晰的透明通道层次比如半透明的玻璃瓶、烟雾、能量体那建议改成Alpha用透明度推高度。大部分普通道具选Luminosity就对了。第二个是Strength也就是法线强度。这个值决定凸起凹陷的剧烈程度。我实测下来平涂插画风格的道具设在60%到80%之间最舒服。低了立体感出不来高了会有一种很假的塑料浮雕感尤其边缘和明暗交界处会出现过度夸张的转折。第三个是Height Scale和Sharpness。Height Scale控制高度图整体的振幅相当于把凹凸整体放大缩小Sharpness控制明暗过渡边缘的锐利程度。这里有个经验原画本身带硬阴影的Sharpness要适度下调否则阴影线会变成一道被算法放大成深沟的假凹陷。第四个是AO强度。Laigter能顺带算出环境光遮蔽贴图这个值我一般开到50%左右。AO贴图叠加在Sprite光照上接触阴影的地方会自然压暗立体感会上去一大截。第五个是高光贴图的Intensity和Size。注意高光图控制的是哪些地方亮不是光源在哪边。金属质感的东西把Intensity调高一点、Size调小一点高光会更聚拢锐利。布、木头这类哑光材质反而要把Intensity压低Size调大让高光柔和铺开。这些参数没有绝对标准我每次都是在预览窗口里转一下光源角度看看金属面上高光是否自然、圆弧处是否有明显折线再微调。整个过程三分钟以内搞定。4.3 导出和命名为引擎导入铺路参数调满意后点击导出。Laigter默认会输出法线贴图、高光贴图、高度贴图和AO贴图四张图分开存。按我的习惯法线贴图命名后缀用_n高光贴图用_s高度图用_hAO图用_ao。这套命名规则不是Laigter强制的但你自己项目里一定要统一不然攒到一百多张贴图的时候找一张图能找半天。导出格式我选PNG因为2D游戏Sprite的alpha通道太重要了PNG无损保留透明信息。注意一点Laigter导出的法线贴图是包含透明通道的也就是说Sprite边缘外是透明像素进入引擎后不会产生奇怪的方块阴影。全部流程走完我专门掐了表从打开Laigter到导出完毕耗时四分半。这就是题目说的五分钟单张平涂转引擎动态受光的实操依据。4.4 备选方案用GIMP Normalmap插件做精修如果遇到需要精细控制的单张图我会转到GIMP的Normalmap插件。路径是滤镜→地图→Normalmap主界面的Scale给2到4之间。这里多解释一句Scale其实控制的是高度场采样时的平滑半径数值越大生成的凹凸越宽缓需要强调细小颗粒质感就把Scale调小需要整体大块的起伏就把Scale调大。Depth映射方式有几种选项线性、均值、高斯渐变等等。实测下来游戏素材用Linear最稳妥不容易在边缘产生振铃状的黑白纹。生成之后如果你觉得立体感不够我习惯复制一个图层叠加模式选Overlay再用亮度对比度微调。这个方法比重新生成一次更快而且不会把边缘搞坏。GIMP路径适合那种生成之后再叠加细节的场景。举个例子程序化生成完基础法线后我想让剑刃开刃的线条更明显就在PS/GIMP里用深色在高度图上画一道线再重新生成一次刃口立刻锋利起来。这种生成手动修正的混合思路后面会有更详细的说明。5. 导入引擎后的动态受光设置与高频翻车现场贴图生成出来只是走了一半路另一半是让它正确地在引擎里参与光照计算。这一步看着简单实际上翻车点非常多。我把Unity、Godot、UE三家的导入设置和排查经验放一起写方便对照。5.1 导入阶段最容易忽略的勾选项以Unity为例选中法线贴图Inspector面板里第一件事就是把Texture Type改成Normal Map。这一步会同时做两件事自动把sRGB勾选关掉并且把压缩格式切到适合法线贴图的那一档。如果你忘记了这一步法线贴图会当作普通颜色贴图被采样光照结果会变得非常奇怪所有凸起都带着一层灰蒙蒙的颜色。Godot里导入设置相对简单在Import面板里把Compress Mode改一下Normal Map选项会自动勾上。UE的话Texture类型选Normal map并且压缩设置选BC5这是对法线贴图精度最友好的压缩格式。有个细节我单独提一下Unity的2D Sprite如果使用内置Sprite-Light光照体系Sprite使用的Material要选Sprite-Lit-Default。很多人贴了法线贴图但光照没反应就是Material还挂在Sprite-Default上这个材质根本不读取法线信息光打了也白打。5.2 一个标准的动态受光验证流程导入设置做完我建议按下面这个流程验证而不是直接丢进游戏场景里看。先在场景里放一个Sprite赋上原图和法线贴图材质用带光照的2D Material。然后在Sprite旁边放一个2D点光源把光源强度拉到一个明显可见的数值。这时候从正上方拖动光源绕着Sprite转一圈观察亮暗变化是否符合直觉。这一步能发现大约八成的问题。光源偏左时Sprite左边应该变亮右边变暗光源从下方打的时候本来朝下的面、比如剑柄底部的暗面应该被照亮。如果发现明暗方向反了比如光源明明在左、左边却变暗那就是法线贴图的绿色通道方向跟引擎约定不一致。解决方法是把贴图的G通道反相也就是做一次颜色反转在PS里快捷键CtrlI之后只保留G通道或者在Unity的导入设置里翻一下相关的Invert Green选项具体名称各版本略有差别。验证完之后再把光源调成动态运动的比如让它在场景里沿一个轨迹移动看看法线是否真的跟着光源方向实时变化有没有闪烁、有没有在特殊角度突然变成全白全黑。这一步没问题动态受光就算真正打通了。5.3 我踩过的三个高频翻车点第一个翻车点是边缘白边加黑边。表现是Sprite轮廓周围有一圈非常细的白色亮边光照下尤其明显。排查链路是这样的先看生成时的Alpha处理Laigter生成法线时如果对半透明像素处理得不好边缘像素的法线方向会被拽向一个奇怪的角度表现在引擎里就是白边。解法不是去引擎里改而是回生成工貝把Alpha剥边或者把半透明边缘裁掉。最省事的方式是生成法线前先对原图做1像素收缩填充让边缘像素的alpha变成不透明再进生成流程。第二个翻车点是整张贴图在光照下像充了气的塑料所有表面都在反光没有材质差异。这个问题八成出在AO或者高光贴图上更常见的是没有用AO贴图导致暗部缺少压暗的信息整个Surface被均匀照亮看起来很飘。解法是把导出的AO贴图挂到受光材质上让接触阴影的地方暗下来。第三个翻车点比较隐蔽出现在2.5D流程里。如果你不是纯2D Sprite而是把贴图贴在Blender模型上再导出FBX进引擎那模型面法线的方向会直接影响法线贴图的效果。模型面法线反了贴图看起来就像整面凹凸都凹陷了。排查方法是在Blender编辑模式里打开面朝向显示Face Orientation蓝色面朝外是正常的红色面就是反的。选中反了的面用重新计算外部Recalculate Outside修正。这个检查最好在导出模型前做进了引擎再查就很绕。注意在2D游戏里处理法线贴图有一个很容易入坑的惯性思维——把法线贴图当成普通纹理来管理。实际上法线贴图的采样值必须在导入设置里保持一致不同引擎之间的通道约定也有细微差异比如某些引擎期望Y轴向下Unity里如果不翻转G通道立体的凹凸方向就会整体颠倒。所以项目从第一天起就要定好法线贴图的标准姿势避免美术资源跨引擎或者跨管线的时候统一反了。5.4 从现象到根因的排查链路示例有一次我从Git上拉了一批新资源里面有一张法线贴图在Unity里怎么调都不对光源从左边来阴影却打在左边。整个排查过程花了我一个多小时记录下来给大家参考。第一步检查导入设置Texture Type确认是Normal Map没有勾选sRGB没问题。第二步检查材质确认挂的是Sprite-Lit-Default法线贴图槽位确实有值也没问题。第三步检查贴图本身的RGB通道。我在PS里打开这张法线贴图放大看金属剑刃区域发现R通道整体往左偏G通道整体往上偏。对照同批其他正常贴图的通道分布马上定位到是这张贴图的G通道与其他贴图反了。原因可能是生成时工具版本不同也可能导出时勾了不同的通道选项。用PS翻转G通道后重新导入光照立刻正常。这个例子的核心经验是引擎报错时先在导入设置和材质上排查如果这两处都没问题再把贴图丢回PS里检查通道分布而不是反复改光源位置或者重新生成贴图。方向性问题大部分都是通道约定不一致导致的跟生成参数关系不大。6. 客观评价这套工作流能解决什么不能解决什么用了几个月的程序化法线生成之后我必须说清楚一件事这套流程不是万能的它擅长解决一部分问题但在另一些场景下手涂法线依然有不可替代的价值。6.1 程序化生成的三个明显短板第一个短板是写实材质表达。程序化生成靠明度推高度它不知道一块区域是金属还是布料。金属需要锐利且明亮的高光布料需要柔和细碎的表面起伏木头需要沿着纹理方向的长条形凹凸——这些都是生成工具无法从颜色里直接感知的。所以如果项目里主打写实风格的2D表现程序化法线只能作为底子后期必须手修。第二个短板是风格化笔触。很多2D原画带有强烈的手绘笔触线条有粗细变化、颜色有晕染效果。手涂法线时这些笔触会被画家翻译成有节奏的凹凸变化而程序化生成时算法把这些笔触全部当作高度信息处理结果就是笔触边缘变成了一道道深浅不一的沟壑画面显得很脏。这种情况在偏水墨、厚涂风格的原画上特别明显。第三个短板是结构认知。算法不理解这是一个铠甲肩部的转折面或者这是眼球和高光的相对位置它只知道明暗梯度。所以遇到结构复杂的图比如角色半身像、复杂机械程序化生成的法线在结构转折处经常是平的甚至错误地凹进去。这也是为什么我在文章开头说批量道具用生成绰绰有余但主角立绘这类关键资产我会留出手工精细处理的时间。6.2 生成手修的混合工作流才是终点我实际在项目里用的不是纯生成也不是纯手涂而是一条混合工作流。流程拉通是这样的先用Laigter或者GIMP生成基础法线这一步解决80%的大形起伏。然后导出到PS/GIMP在高光层上手动补关键的材质细节。比如剑刃开刃的高光条、符文刻痕的凹槽、布料褶皱的主趋势方向这些细节用深色或浅色在高光图上直接画比在法线图上画更直观、也更好控制。画完之后把修改过的高光图和原法线图用Overlay图层混合模式叠起来生成一张新的最终法线贴图。这个做法相当于用颜色覆盖来修正方向视觉上你画的是明暗关系但叠加后实际的法线方向也会跟着微调。熟练之后单张角色立绘的法线精修能控制在20分钟左右比全程手涂快一个量级质量还有保证。如果你手边没有绘画软件也可以用AI辅助那套路子。用ControlNet的Depth/Normal预处理器从一张原图推理出法线贴图底子再人工检查修正。这个方案对复杂构图支持更好但我个人觉得对小道具而言杀鸡用牛刀了反而是批量效率不如Laigter来得干脆。6.3 回到效率本身这套工作流适合谁说句实在话程序化生成法线真正的价值是让那些不够重要、但必须有的资源不再占用大量手工时间。木箱、石块、药瓶、路标这类场景道具玩家根本不会凑近了仔细看它的法线是不是手绘的但它们在动态光照下必须看起来是立体的、是有体积的。程序化生成恰恰填上了这个产能缺口。另一个很适合的场景是序列帧。角色攻击动作会有五六张连续的动作帧手涂法线意味着每一帧都得画一遍工作量爆炸。Laigter支持直接把序列帧拖进去批量生成每张共用一套参数出来的一致性还特别好不会出现这一帧立体感强、下一帧立体感弱的情况。我自己现在的做事方式已经固定下来了接到道具类资源默认先进Laigter走一遍程序化导出的贴图直接进引擎看效果确认基础效果OK之后只针对主角、关键NPC、重要剧情道具做一轮手修叠加。手绘能力没有被扔掉只是把它用在了更需要人判断的地方。最后分享一个每次换新项目都会做的小动作在项目启动时花半天时间把内部要用的法线生成参数、命名规则、导入设置文档整理好。别看这半天占的时间不多它能让后面几十个资源的生产流水线不卡壳比我当初一张一张手涂法线的时候省心太多了。