导入3D场景

Godot 场景导入器

在处理 3D 素材时,Godot 有一个非常灵活且可配置的导入器.

Godot 使用 场景 工作.这意味着用您最喜爱的3D软件制作的整个场景可以尽可能完整地被导入.

Godot支持以下 3D 场景文件格式:

  • glTF 2.0 (建议使用).Godot完全支持文本( .gltf )和二进制( .glb )格式.

  • DAE (COLLADA):一个比较老的格式,当然完全支持.

  • OBJ(Wavefront)格式+他们的MTL材质文件.这也是完全支持的,但相当有限(不支持枢轴、骨架、动画、PBR材质……).

  • ESCN,是Godot特有的格式,Blender可以用插件导出.

  • FBX:通过 Open Asset Import library 提供支持.然而,FBX 是专属格式 ,所以如果无特殊要求的话,推荐使用上面列出的格式.

只需将场景文件和纹理一起复制到项目存储库中,Godot 就可以完全导入.

在输出时,网格不会被骨骼变形很重要.在使用您喜欢的3D编辑器进行导出之前,请确保将骨骼重置为其T姿势或默认的静止姿势.

从Maya和3DS Max导出的DAE文件

Autodesk 为 Maya 和 3DS Max添加了内置的 COLLADA 支持,但默认情况下已损坏,因此不应使用.导出此格式的最佳方法是使用 OpenCollada 插件.尽管它们并非总是与最新版本的软件保持一致,但它们可以很好地工作.

从Blender导出glTF 2.0文件

有三种方法可以从Blender导出glTF文件.作为一个glTF二进制文件(.glb 文件)、嵌入的glTF(.gltf 文件)、和使用纹理(gltf + .bin + 纹理).

glTF二进制文件是三个选项中最小的一个.它们包括在Blender中设置的网格和纹理.当放入Godot中时,纹理将成为对象材质文件的一部分.

glTF嵌入式文件的功能与二进制文件相同.它们没有在Godot中提供额外的功能,也不应使用,因为它们的文件较大.

将glTF与纹理分开使用有两个原因.一种是将场景以基于文本的格式和二进制数据,描述在单独的二进制文件中.这对于版本控制很有用,如果要基于文本格式评审更改.第二种是您需要将纹理文件与材质文件分开.如果您不需要这些glTF二进制文件的任一个,也可以.

注解

Blender导出的glTF文件不会包含放射纹理.如果您的模型使用这种文件,则必须单独分开导入.

从Blender导出的DAE文件

Blender也有内置的 COLLADA 支持,但不能满足游戏引擎的需求,不能完全正常工作,不应该使用.

Godot提供了一个 `Blender插件<https://github.com/godotengine/collada-exporter>`_ ,可以正确导出COLLADA场景,供Godot使用.它不能在Blender 2.8或更新的版本中使用,但有计划在未来更新它.

从Blender导出ESCN文件

最强大的一个,叫做 godot-blender-exporter .它使用的是.escn文件,这也是.tscn文件(Godot场景文件)的另一种名称;它从Blender场景中保留了尽可能多的信息.然而,它被认为是试验性的.

ESCN导出器有一个详细的 文档 ,描述了它的功能和用法.

单独导出纹理

虽然纹理可以和模型一起以某些文件格式导出,如glTF 2.0,但您也可以单独导出它们.Godot的材质使用PBR(基于物理的渲染),所以如果一个纹理程序可以导出PBR纹理,它们就可以在Godot中工作.这包括 Substance suite , ArmorPaint (开源) , Material Maker (开源) .

注解

关于Godot材质的更多信息,参见 空间材质 .

导出注意事项

由于GPU只能渲染三角形,所以包含四边形或N-gons的网格必须在渲染前进行 triangulated 三角剖分.Godot可以在导入时对网格进行三角剖分,但结果可能无法预测或不正确,特别是对于N-gons.无论目标应用是什么,在导出场景之前进行三角剖分会得到更一致的结果,因此应该尽可能地进行三角剖分.

为了避免在Godot中导入后出现三角剖分不正确的问题,建议让3D DCC自行对对象进行三角剖分.在Blender中,可以通过向对象添加三角剖分修改器,并确保在导出对话框中勾选 应用修改器 来实现.另外,根据导出工具的不同,您可以在导出对话框中找到并启用 Triangulate Faces 选项.

为了避免在编辑器中出现3D选择的问题,建议在导出场景前在3D DCC中应用对象变换.

导入工作流程

Godot场景导入器允许有关如何导入数据的不同工作流.根据许多选项,可以通过以下方式导入场景:

  • 外部材质(默认):将每种材质保存到文件资源的位置.保留对它们的修改.

  • 外部网格:每个网格被保存到不同文件的位置.许多用户喜欢直接处理网格.

  • 外部动画:允许在源更改时,修改和合并保存的动画.

  • 外部场景:将每个导入场景的根节点保存为单独的场景.

  • 单场景:内置所有内容的单场景文件.

../../../_images/scene_import1.png

由于不同的开发人员有不同的需求,因此此导入过程是高度可定制的.

导入选项

导入器有几种选项,这将在下面讨论:

../../../_images/scene_import2.png

节点

根类型

默认情况下,导入场景中根节点的类型为 Spatial,但是可以对其进行修改.

根名称

允许为生成的根节点设置特定名称.

根规模

根节点的规模.

自定义脚本

可以提供一个特殊脚本,来处理导入后的整个场景.这非常适合后期处理、更换材质、对几何图形做有趣的事情等.

创建如下的脚本:

  1. tool # Needed so it runs in the editor.
  2. extends EditorScenePostImport
  3. func post_import(scene):
  4. # Do your stuff here.
  5. return scene # remember to return the imported scene

post_import 函数将导入的场景作为参数(参数实际上是场景的根节点).必须返回最终将要使用的场景.它可以是不同的.

存储

默认情况下,Godot导入一个单独的场景.此选项允许指定根下面的节点将是一个单独的场景,并被实例化到导入的场景中.

当然,在其他地方手动实例导入的场景也是可以的.

材质

位置

Godot 支持网格或节点中的材质.默认情况下,材质将放置在每个节点上.

存储

材质可以存储在场景中或外部文件中.默认情况下,它们存储在外部文件中,因此可以进行编辑.这是因为大多数 3D 数字创作软件没有与 Godot 中的相同的材质选项.

当材质是内置的时,每当源场景被修改并重新导入时,它们都会丢失.

注解

除非你在重新导入之前删除相关的 ``.material``文件,否则Godot不会重新导入存储在外部文件中的素材.

如要在每次重新导入 3D 场景时强制重新导入材质,请在文件系统面板中选中 3D 场景中的材质存储模式,然后进入导入面板,将 材质 > 存储 设置为 内置 而不是 文件.

保持开启重新导入

一旦将材质编辑为使用Godot功能,导入器将保留已编辑的材质,并忽略来自源场景的材料.仅当材质保存为文件时,此选项才存在.

网格

压缩

使网格对网格的多个方面使用不太精确的数字以节省空间.

这些是:

  • 变换矩阵(位置、旋转、和缩放):32位浮点数到16位有符号整数.

  • 顶点:32 位浮点数到16位有符号整数.

  • 法线:32 位浮点数到32位无符号整数.

  • 切线:32 位浮点数到32位无符号整数.

  • 顶点色:32 位浮点数到32位无符号整数.

  • UV:32 位浮点数到32位无符号整数.

  • UV2:32 位浮点数到32位无符号整数.

  • 顶点权重:32 位浮点数到32位无符号整数.

  • 骨架骨骼:32 位浮点数到16位无符号整数.

  • 数组索引:基于具体有多少元素,32位或16位无符号整数.

附加信息:

  • UV2 = 用于细节纹理和烘焙光照纹理的第二个 UV 通道.

  • 数组索引 = 一个数字数组,它为上面数组的每个元素计数;即, 它们的顶点和法线的数量.

在某些情况下,这可能会导致精度损失,因此可能需要禁用此选项.例如,如果网格非常大或导入了多个网格覆盖巨大的区域,则压缩此网格的导入,可能会导致几何图形的间隙、或顶点不在它们应在的位置.

确保切线

如果要使用法线贴图的纹理,网格需要有切线阵列.此选项可确保如果这些阵列在源场景中不存在,则生成它们.Godot 使用 Mikktspace 来做这件事,但最好让它们在导出器中生成.

存储

网格可以存储在单独的文件(资源)中,而不是内置的.除非有人想直接用它们建立对象,否则这没有多少实际用途.

提供此选项是为了帮助那些喜欢直接使用网格而不是场景的人.

光线烘焙

网格是否用于烘焙光照贴图中.

  • 禁用: 网格未用于烘焙的光照贴图中.

  • 启用: 网格用于烘焙的光照贴图中.

  • Gen光照贴图: 网格用于烘焙光照贴图中,并为光照贴图展开第二个UV层.

注解

有关光线烘焙的更多信息,请参阅 烘焙光照贴图.

外部文件

生成的网格和材质可以选择存储在具有场景名称的子目录中.

动画选项

Godot提供了许多有关如何处理动画数据的选项.一些导出器(如Blender)可以在一个文件中生成许多动画.其他的,如3DS Max 或 Maya,需要将许多动画放入同一时间线,或者最糟糕的情况是将每个动画放在单独的文件中.

../../../_images/scene_import3.png

默认情况下启用动画导入.

注意

要修改导入的 3D 场景中的动画,您需要在导入栏中将动画存储选项从 内置 改为 文件 .否则,在项目运行时,对Godot中的动画所做的修改将丢失.

FPS

大多数3D导出格式都以秒而不是帧的形式存储动画时间轴.为确保尽可能真实地导入动画,请指定用于编辑动画的每秒帧数.未能这么做,可能会导致动画不稳定.

过滤器脚本

可以使用特殊语法指定过滤器脚本,以决定应保留哪些动画的哪些轨道.

过滤器脚本会针对每个导入的动画执行.语法由两种类型的语句组成,一种用于选择要过滤的动画,另一种用于过滤匹配的动画中的各个轨道.所有名称模式均使用不区分大小写的表达式匹配,可以使用通配符 ?* (内部使用 String.matchn() ).

脚本必须以动画过滤器语句开头 (如以 @ 开头的行表示). 例如,如果我们想要将过滤器应用在所有以 "_Loop" 结尾的导入动画上:

  1. @+*_Loop

同样地,还可以在同一行中添加其他模式,以逗号分隔.下面是一个修改后的例子,它额外*包含*所有名称以 "Arm_Left" 开头的动画,同时*排除*所有名称以 ``“Attack”``结尾的动画:

  1. @+*_Loop, +Arm_Left*, -*Attack

在动画选择过滤器语句之后,我们添加轨道过滤模式来指示保留或丢弃哪些动画轨道.如果未指定轨道过滤器模式,则匹配动画中的所有轨道都会被丢弃!

需要注意的是,轨道过滤器表达式是按顺序作用于动画中的每条轨道,这意味着,一行表达式可能包含某个轨道,但后续的规则仍然可以忽略它.同样,一个被之前规则排除的轨道,可能被过滤器脚本后续的规则重新包含进来.

例如: 包含动画中所有名字以``“_Loop”结尾的轨道, 但忽略任何以“Control”结尾的“Skeleton”轨道,除非它们的名字中有 ``"Arm":

  1. @+*_Loop
  2. +*
  3. -Skeleton:*Control
  4. +*Arm*

在上面的示例中,如像``“Skeleton:Leg_Control”`` 这样的轨道会被丢弃,而像``“Skeleton:Head”`` or ``“Skeleton:Arm_Left_Control”``这样的轨道会被保留.

任何不是以 + 或``-``开头的轨道过滤器行将会被忽略.

存储

默认情况下,动画保存为内置.可以将它们保存到一个文件中.这允许向动画添加自定义轨道并在重新导入后保留它们.

优化

导入动画时,会运行优化程序,从而大大减少动画的大小.一般情况下,除非您怀疑动画可能因启用而被破坏,否则应始终启用此功能.

剪辑

可以指定单个时间轴中的多个动画作为剪辑.这样做的话,模型必须只有一个命名为``default``的动画.为了创建剪辑,把剪辑数量改成比0大的数.然后可以修改剪辑名字,指定开始和结束帧,选择动画是否循环.

场景继承

在许多情况下,可能需要对导入的场景进行修改.默认情况下,这是不可能的,因为如果源素材发生更改(从3D建模应用程序重新导出了源 .dae.gltf.obj),Godot将重新导入 整个场景.

但是,可以使用 场景继承 进行本地修改.尝试打开导入的场景,将出现以下对话框:

../../../_images/scene_import4.png

在继承场景中,修改的唯一限制是:

  • 无法删除节点(但可以在任何位置添加).

  • 子资源无法被编辑(如上所述它们将保存在外部)

除此之外,一切都是允许的!

导入提示

很多时候,编辑场景时,导出后需要完成一些常见任务:

  • 向对象添加碰撞检测.

  • 将对象设置为导航网格.

  • 删除游戏引擎中未使用的节点(例如用于建模的特定光源).

为简化此工作流程,Godot提供了一些后缀,可以将其添加到3D建模软件中的对象名称中.导入后,Godot将检测到它们并自动执行操作.

注解

下面描述的所有后缀都 大小写敏感.

删除节点(-noimp)

具有此后缀的节点名称将在导入时被删除,不管它们的类型是什么.它们不会出现在导入的场景中.

创建碰撞体(-col, -convcol, -colonly, -convcolonly)

-col``选项只作用于网格物体.如果该选项被检测到,将会添加一个静态碰撞体的子节点,用的是跟网格一样的几何体.这会创建一个三角形网格碰撞体,这个选项对碰撞检测来说很慢但是精确.这个选项通常是关卡几何体需要的(但是也看看下面的-colonly`` ).

``-convcol``选项将创建 一个 ConvexPolygonShape 而不是 ConcavePolygonShape.不像可以是凹型的三角形网格,一个凸型的形状只能精确的表示它没有任何凹型角度(金字塔是凸型,但空盒子是凹型).因此,凸型碰撞体通常不适用于关卡几何体.当说到一个很简单的网格时, 凸型碰撞体相对三角形碰撞体有更好的性能.这个选项适用于简单的物体,或是需要大多数时精确碰撞检测的动态物体.

然而,在这两个例子中,视觉几何体处理过于复杂或不够光滑的碰撞,物理引擎会出现小故障从而不必要的降低了引擎的速度.

为了解决这个问题,存在 -colony 修饰符,该修饰符将在导入时删除网格,并创建一个 StaticBody 静态碰撞体.这有助于将可视网格和实际碰撞体分开.

选项 -convcolonly 已相似的方式工作,但将创建一个 ConvexPolygonShape 而不是一个 ConcavePolygonShape.

选项 -colonly 也可以与Blender的空对象一起使用.导入时,它将创建一个带有碰撞节点的 StaticBody 作为子节点.碰撞节点将具有许多预定义的形状之一,具体取决于Blender的空绘制类型:

../../../_images/3dimp_BlenderEmptyDrawTypes.png

可能的话, 试着使用少量简单的碰撞体 而不是三角形网格或凸型体.简单的形状常常有最好的性能和可靠性.

注解

为了Blender编辑器中更佳的可见性,可以在碰撞空物体上设置”透视”选项,并在Blender的 用户偏好设置> 主题> 3D视图> 空物体 中为它们设置不同的颜色.

参见

碰撞体全面概述请查看 碰撞形状(3D).

创建导航(-navmesh)

具有 -navmesh 后缀的网格节点,将被转换为导航网格.原始网格节点将在导入时被删除.

创建一个 VehicleBody (-vehicle)

具有 -vehicle 后缀的网格节点,将作为一个 VehicleBody 节点的子节点被导入.

创建一个 VehicleWheel (-wheel)

具有 -wheel 后缀的网格节点,将作为一个 VehicleWheel 节点的子节点被导入.

刚体(-rigid)

具有 -rigid 后缀的网格节点,将作为一个 RigidBody 节点的子节点被导入.

动画循环(-loop-cycle)

COLLADA文档中以令牌 loopcycle 开头或结尾的动画剪辑将作为设置了循环标志的Godot动画导入.**这是区分大小写的,不需要连字符.**

在Blender中,这需要使用NLA编辑器,并用 loopcycle 前缀或后缀命名该动作.