从 Unity 到 Blender:用 FBX 或 glTF 导出模型,以及导入后要修的问题
Unity 是 Y 轴向上的左手坐标系,Blender 是 Z 轴向上的右手坐标系,中间那个文件必须同时活过这两端。两条导出路线、导入面板里真正该改的字段,以及第一次导入的修复对照表。
从编辑器里的 Surface Material Override 到运行时的 GDScript 替换,再到会让同款模型集体变色的共享资源问题,顺带把 PBR 取值与贴图导入设置讲清楚。
Godot 4 不会把材质存在导入的 GLB 文件里。文件只在导入阶段被读取一次,之后材质要么待在项目内的网格资源上,要么待在场景里的 MeshInstance3D 节点上。分清楚自己改的是哪一处,原本很绕的操作基本几十秒就能做完。
本文按顺序讲四件事:编辑器里的 Surface Material Override 怎么用,运行时用 GDScript 怎么换,StandardMaterial3D 与 ShaderMaterial 各自适合什么场合,以及共享资源为什么会让一次改色波及关卡里所有同款模型。
把 GLB、glTF 或 FBX 文件导入 Godot 4 项目时,导入器会生成一个网格资源。文件里描述的材质以表面材质的形式保留在这个网格内部,导出时写了几个材质槽就有几个表面。引用该网格的 MeshInstance3D 节点既能一次性覆盖全部材质,也能只覆盖某一个表面,两种做法都不会改动导入的原始资产。
最终看到什么由三个属性决定,而且它们的优先级是固定的。Material Override 压过其他一切;指定索引的 Surface Material Override 压过该表面自带的材质;网格上的表面材质则是没有任何覆盖时的兜底。这三者都保存在场景里,或者保存在你自己另存的 .tres 资源里,磁盘上的 .glb 永远不会被回写。
| 属性 | 作用范围 | 典型用途 |
|---|---|---|
| Material Override | 该节点的全部表面 | 调试材质、统一着色、快速看效果 |
| Surface Material Override(索引 N) | 仅一个表面 | 只改多材质模型里的某个部件 |
| 网格资源上的表面材质 | 所有共用该网格的实例 | 随导入文件一起进来的默认材质 |
| GDScript 中设置的 material_override | 运行时作用于全部表面 | 受击闪红、队伍颜色、选中高亮 |
场景面板不会列出表面索引,最快的定位办法是给索引 0 挂一个鲜红色的 StandardMaterial3D,然后逐个把索引往上加,直到你要改的部件变红。从 Blender 导出的车身通常带三到六个表面,编号顺序由导出器决定,所以玻璃并不一定在索引 1。导出前先给材质重命名会有帮助,因为材质名会经由 glTF 带进 Godot。
StandardMaterial3D 是内置的 PBR 资源,它替你编译成着色器,并把基础色、金属度、粗糙度、法线、环境光遮蔽、自发光、透明和剔除方式暴露成检查器字段,GDScript 里也有同名属性。ShaderMaterial 运行的是用 Godot 着色语言写的代码,凡是标准字段表达不了的效果都得靠它:水面的 UV 滚动、扫描网格上的三平面映射、卡通分层、溶解消失、顶点位移。标准资源搭起来更快,而一旦效果不再是表面属性,着色器资源就是唯一选择。
| 需求 | StandardMaterial3D | ShaderMaterial |
|---|---|---|
| 纯色或一整套 PBR 贴图 | 内置支持,无需写代码 | 能做,但属于多余的工作量 |
| 金属度、粗糙度、自发光、透明 | 检查器字段直接调 | 必须手写 |
| UV 滚动、顶点动画、溶解 | 做不到 | 这个资源存在的理由 |
| 不懂着色器代码的美术也能改 | 可以 | 只有把 uniform 写清楚才行 |
| 出错时的表现 | 数值不对,立刻能看见 | 运行时编译报错或直接变黑 |
贴图导入设置决定了上面这些能不能留到最后。Godot 4 的贴图导入面板提供 2D、3D、Normal Map 和 Detect 3D 几个预设:基础色与 ORM 贴图用 3D,法线贴图用 Normal Map,这样才能保留法线贴图需要的绿通道处理。如果法线贴图完全没有效果,常见原因是网格缺少切线,而 glTF 导入选项可以生成切线(Godot 4.x 里这个选项叫 Ensure Tangents)。
运行时的替换是搭出受击状态、队伍颜色和选中高亮的常规做法,不必复制整个场景。实例级接口都接收 Material 资源,所以套路是:材质只构建一次,保留引用,状态变化时再赋给节点。两个调用能覆盖大多数情况:material_override 作用于整个节点,set_surface_override_material 配合索引作用于单个部件。每个实例都不一样的数值,例如色调或闪烁相位,可以声明成实例 uniform,再用 set_instance_shader_parameter 设置,不必为此复制材质。
导入的材质是一份被所有使用它的节点共享的资源。给一个敌人设置 albedo_color,关卡里三十个敌人会一起变色,因为它们背后只有一份材质。Godot 会在检查器里给被多个节点使用的资源加一个小标记,动手改代码之前靠它就能确认问题。
第二种做法值得单独提醒一句代价。Local to Scene 会连同资源下面的一切一起复制,所以把它开在网格上而不是材质上,顶点数据也会被复制,场景里每个实例的内存占用都会上升。复制材质很便宜,因为贴图仍按引用共享;复制网格则不便宜。对于来自 AI 生成器或素材包里的资产,先确认关卡里到底摆了多少个副本,再决定要不要走逐实例这条路;这些改动都不会写回源文件。
关于开箱即用的资产:从 Open3DAI 导出的 GLB 通常已经把基础色贴图接在表面材质上,所以 Godot 里的工作往往从覆盖槽位开始,而不是从图像软件开始。Open3DAI 支持导出 GLB、glTF、OBJ、STL、PLY 和 3MF,但不替你展开 UV、重拓扑或修复网格,需要干净 UV 岛的重绘仍然要放到 Blender 里做。引擎可用性、积分定价和第三方条款都会变化,做预算之前请以厂商页面为准。
因为材质是共享资源。所有使用同一个网格的 MeshInstance3D 都指向同一份材质,改 albedo_color 改的是它们共读的那一份。可以对材质做复制、打开 Local to Scene,或者改为通过实例着色器参数制造差异。
Material Override 用一份材质替换该节点的全部表面;Surface Material Override 是数组,每个表面索引一个条目,只有填了的条目才会被替换。整体换材质用前者,只有单个部件不同时用后者。
当效果不再是表面属性的时候:UV 滚动、顶点位移、溶解、UV 质量差时的三平面映射、卡通分层。如果只是颜色、贴图加标准 PBR 字段,StandardMaterial3D 搭得更快,团队其他人也更容易改。
材质只构建一次并保留引用,然后赋给节点:整个节点用 material_override,单个表面用带索引的 set_surface_override_material。之后直接改材质属性,不要每帧重新查找节点。
先看导入预设,法线贴图应该用 Normal Map 而不是 3D;再看网格,解读法线贴图必须有切线基,确认导入时生成了切线(glTF 选项里叫 Ensure Tangents),并确认材质法线槽位上确实挂了这张贴图。
先数清网格有几个表面,然后在 Surface Material Override 数组里只填对应的索引。索引不确定时,给索引 0 挂一份鲜红材质,逐个往上加,直到目标部件变红,再把测试材质清掉。
不会。在 Godot 里创建的材质保存在场景里,或者保存在你自己另存的 .tres 资源里。从 Blender 重新导出会覆盖导入器生成的内容,编辑器里的覆盖也会在重新导入时丢失,所以在意的材质要存成外部资源。
常见原因大致按顺序是:基础色被留成了黑色;本该不透明的材质开了透明;模型是单面几何却把剔除模式设成了单面;网格法线朝内。片段着色器写坏的 ShaderMaterial 同样什么都不渲染,错误会在调试器里报出来。
不能,也没必要。切片软件读的是几何体,而 STL 根本不携带材质信息。如果颜色要一路带到打印流程里,就从保存模型的那个工具导出 3MF 或 GLB,再在那边指定耗材或颜色。
把同一份提示词或图片交给多个引擎,并排对比网格,然后导出 GLB、glTF、OBJ、STL、PLY 或 3MF。注册即赠免费积分,无需信用卡。
Unity 是 Y 轴向上的左手坐标系,Blender 是 Z 轴向上的右手坐标系,中间那个文件必须同时活过这两端。两条导出路线、导入面板里真正该改的字段,以及第一次导入的修复对照表。
贴图是四个按顺序做出的决定:模型是否需要 UV、UV 岛如何排布、要制作哪几张 PBR 贴图、像素从哪里来。下面逐条给出判断依据和具体数值。
导出格式的选择取决于下一个打开它的软件,而不是文件体积。本文说明 GLB、glTF、OBJ、STL 与 FBX 各自携带什么、会悄悄丢掉什么,以及生成工具不提供 FBX 时该怎么走通这条路。