准备
本篇使用:UE4 4.20版本、VS2017、3dsMax2019以及Python 2.7.13。
工具需求
一些3A游戏大厂的引擎项目中拥有多年积累的丰富的材质库以及重复利用的模型模组,尤其是地面、墙面或建筑外立面以及它们通用的四方连续材质或纹理。通过调整材质的UV参数去对齐模组无法做到精确。一个模组上多种材质,翻找材质对应贴图依次导出,再导入3dMax做材质球去调整模型UV是一项浪费时间的体力活。于是有了“引擎材质----->3dsMax材质”批量转换的工具,UV的调整针对BaseColor和Normal即可。
最终的完成效果:
UE4材质资源烘焙纹理
渲染材质属性到纹理
创建新插件,空模板即可。然后创建UObject的衍生类即可,此处命名为OutputTexture。如果你想把很多个小工具或者小模块做在一个插件包里,那么只需要把每个module都写入.uplugin文件,如下图。
OutputTexture的头文件声明一个蓝图可调用的函数ExportMaterialTexture,由于引擎自带的BakeTexture功能对应的API——RenderMaterialPropertyToTexture为private,所以我们只需要在我们的类中把它声明和实现复制一下即可。
OutputTexture.h:
FileName就是存储路径及名称,以.bmp结尾;Material就是输入的材质接口,可以是母材质,也可以是材质实例;MaterialProperty是枚举类型的变量,可以选择几乎所有材质引脚的最终输出值。
注意:源码中针对此枚举中元素的注释位于行末,但此注释会自动变为下一行的解释说明。。。于是BaseColor的解释说明其实是针对前一行的,但前面两行在引擎中是不可见的。所以不要误会,无视注释即可。
方法的实现如下。
OutputTexture.cpp:
首先会判断我们提供的材质的混合模式以及提供的材质属性是否有效,如果有效则渲染材质到贴图,贴图的分辨率由该材质属性(如BaseColor, Normal等)连接的贴图最大分辨率决定。如果无效,那么返回分辨率为1x1的红色。
因为此处要用到MaterialUtilities这个模块,所以.Build.cs文件中要补充上。
4.20 Blutility扩展编辑器
如果你正在使用4.20版本,那么很幸运,你可以轻松创建一些编辑器的自定义操作功能。
首先打开偏好设置,开启处于实现性功能的Blutility。
然后在工程的Content或者插件的Content中创建Blutility类蓝图。
对场景中的Actor操作则选ActorAction,我们现在要对资源操作,所以选择AssetAction。
双击打开。。开。。开。。开不开。。。。目前还有点BUG,默认打开的是参数面板,那么需要右键该蓝图选择Edit Blueprint。
下面步骤十分重要,创建函数或者自定义事件,个人建议自定义事件。自定义事件勾选Call In Editor。
蓝图十分简单,首先获取选择的资源,如果是材质,那么将它的BaseColor和Normal渲染纹理到指定路径下,并且前缀为材质名称,后缀为属性名称。
编译蓝图,选择材质右键即可看到刚刚创建的自定义操作,点击之后在指定路径下便可以看到渲染出来的纹理。
我们又近了一步。
批量转换与文件写入
设想一个情况:我们选择第一批材质球导出贴图,在Max里生成对应的一批材质球,这个很容易实现。Python脚本只需要遍历一下存放贴图路径的所有贴图。 但是第二次选择不同的材质,导出新的贴图,旧的贴图不能删除或覆盖(原材质变得无效)那么Max的Python脚本再去遍历然后剔除之前使用过的贴图然后去创建材质球则显得拖泥带水,尤其是此路径积累大量贴图之后,更加无意义。
我能想到的一个办法就是把当前选中的材质导出的贴图的路径存入一个临时文本,每次批量选择导出的时候重写此文本内容。
回到OutputTexture.h中,创建新的函数WriteNamesToFile,我们要把收集到的材质名(路径)存到文本里。
OutputTexture.h:
进入OutputTexture.cpp完成实现方法。
OutputTexture.cpp:
方法制作完毕,回到蓝图输入我们要存入文本的内容。
为了后面在Python中按每行生成一个材质球,此处让一个材质球的BaseColor和Normal贴图路径写在同一行,然后Append一个SHIFT+ENTER进行换行操作。
终于,引擎中的插件制作就告一段落了。完整代码如下。
OutputTexture.h:OutputTexture.cpp:3dsMax批量生成材质的Python脚本制作Python脚本
Max内置对应的Python API,虽说不如原生的MaxScript那么面面俱到,但是大部分的功能都是没问题的。
只是用Python写Max脚本的人很少,资料也只有文档,所以要反复碰壁才行。
基础的Python脚本编写可以看我博客的入门篇:
https://cuihongzhi.com/2018/10/27/python/basicmaxpython/basicmaxpython/
下面是我头破血流尝试出来的一套稳如狗的流程,API难觅但用法相对简单,参数很少。根据我的注释便可理解。
TexToMat.py:
坑我比较久的地方是需要先生成NormalBump类型的贴图赋予Bump,然后把我们的Normal图放入其中的Normal。
制作快捷按钮
用MaxScript制作按钮很方便。脚本内容是运行上面编写的Python脚本。
MaxScript:
短的惊人,只需要注意设置路径即可。
全选MaxScript的内容,拖拽到工具栏便自动生成按钮。右键可编辑图标或删除。
最后需要注意一点的是,Max的材质的格子有排序问题。选择6X4是正确的,否则会有一些材质球出格。
大功告成,下面就可以利用这些材质把你的UV安排的明明白白。希望对你有所启发。
THE END
非常感谢大家一如既往的支持。
领取专属 10元无门槛券
私享最新 技术干货