OBJ 模型格式适配
OBJ 是一个被很多三维建模软件所支持的模型格式。
在使用 OBJ 模型时会用到多种文件,.obj
文件存储着物件的几何形态、各个 部件、及要显示的面到 材质 的对应关系, .mtl
文件存储着各个 材质 到 贴图 路径信息的对应关系,而 .png
文件(下称贴图)是要使用的 贴图。每个面有一个材质名称,而每个材质有一个贴图文件名和一个颜色属性。
OBJ 和 MTL 文件可以使用任意文本编辑软件(如记事本、Notepad3、VSCode)等打开查看内容。
贴图
在 OBJ 文件中,mtllib
指令设定这个 OBJ 文件所使用的 MTL 文件,usemtl
指令设定面和材质的对应关系;在 MTL 文件中,newmtl
创建材质,Kd
设定材质颜色,d
设定材质透明度,map_Kd
设定材质对应的贴图。大多建模软件可选择在导出 OBJ 的同时导出 MTL 文件。
如果 OBJ 内有 mtllib
指令(多数建模软件在导出时选中导出 MTL 会自动添加)的话,会自动解析对应的 MTL 文件。会自动解析相对路径,在 OBJ 里的 mtllib
处不需要写完整的 mtr:……
资源位置。
和 BBMODEL 只能使用一张贴图不同,MTL 文件本身就有设定贴图的功能。NTE 使用以下方法为模型设定贴图:
- 如果 OBJ 模型内有
mtllib
指令,将根据 MTL 内对应材质的map_Kd
设定贴图(使用建模软件导出 MTL 时通常就会对应地设定好它)。如此时 OBJ 内有usemtl mat1
,MTL 内写着newmtl mat1
有map_Kd 1995default.png
,那么将会使用1995default.png
给它作为贴图。同时 MTL 内的Kd
、d
设置也会被采用。 - 如果 OBJ 模型内没有
mtllib
指令,NTE 将把材质的名称作为贴图文件名称。如此时一个叫作mat1
的材质就会使用 OBJ 同目录下的mat1.png
作为贴图。特别地,名为_
的材质将会被设为全白。 这个特性允许您不用 MTL 文件(如您感觉多个文件较碍事)。 - 如果使用了一个文件名为
default.png
的贴图,它可以被替换为mtr_custom_resources.json
或其他场合的 JSON 中的设定值,以便更换。详见对应处的说明。
请尽量减少贴图张数,将多张图片尽量合并到一张大图中。图片张数越多性能越差。
UV 坐标
UV 坐标用于解释贴图的哪一部分应当被如何地贴在模型表面上。
将一些模型放入 NTE 时可能发现贴图上下颠倒。这是由于 OBJ 格式没有明确规定 V 坐标正方向应该向上还是向下,NTE 按照 V 坐标正方向向下来读取,而一些建模软件是按照 V 坐标正方向向上来导出 OBJ 的,结果就是上下颠倒了。
在使用 OBJ 模型的地方,NTE 允许指定一个 flipV
设定。在上述的情况下将其打开,NTE 就会反过来读取,让贴图的显示正确。
建模软件 | V 正方向 | 是否需要反转 |
---|---|---|
Blender | 向上 | 需要添加 flipV |
Blockbench | 向上 | 需要添加 flipV |
Metasequoia | 向下 (不勾选反转 V 时) | 不需要 |
部件
OBJ 中可以有 分组 (部件) 信息,如门和车身处于不同分组 (部件),使得可以通过选择部件进行移动来让开门时门独立于车身移动。
在 OBJ 文件中,g
或 o
指令设定分组 (部件)。大多建模软件导出 OBJ 时可选择一并导出分组信息。当文件里同时有 g
和 o
指令时只会按照先出现的一种进行分组。
渲染阶段
严格来说,NTE 并不像 MTR 本体一样按照阶段依次处理各个分组,所以这个“渲染阶段”的称呼对于 NTE 来说有些不太贴切,但我们仍然沿用这个称法。
MTR 有着 exterior
、interior
、interiortranslucent
、light
等多个 渲染阶段 (stage)。具体来说:
- 标为
exterior
的面根据列车所在位置的环境亮度调整亮度,且不支持半透明(贴图内半透明或 d 的半透明面会变全不透明) - NTE 额外添加了
exteriortranslucent
,根据列车所在位置的环境亮度调整亮度,且支持半透明 - 标为
interior
的面总是全亮度(因为车内有灯么),且不支持半透明 - 标为
interiortranslucent
的面总是全亮度,且支持半透明 (顺带一提,它在模型属性文件里叫INTERIOR_TRANSLUCENT
) - 标为
light
的面与interior
一样总是全亮度,并且它不受法线角度的阴影效果影响,还在支持的光影下有泛光效果。但不支持任何透明(贴图内半透明或全透明颜色都会显示为实心) - NTE 额外添加了
lighttranslucent
,是light
的半透明支持版。但由于原版设定此类型不写入深度缓存,它与稍后渲染的其他实体等之间的遮挡关系一定不正确(原版中它是最后处理的所以无所谓和之后的了,但 NTE 里并不是最后所以会有问题)。所以请只将其作为灯外围的小范围泛光效果来使用(如 NTE 自带的 DK3/D51 的头灯) - NTE 不支持
ALWAYS_ON_LIGHT
,且不区分light
和ALWAYS_ON_LIGHT
,即light
在列车在车库时也点亮
未设置时,默认的渲染阶段是exterior
。
这些渲染阶段可以通过和使用 BBMODEL 时相同的方式,在模型属性里对部件进行设置。
特别地,为了方便建模,NTE 额外支持通过 OBJ 的材质名称而不是 MTR 模型属性来设置渲染阶段。在材质名称后加 #渲染阶段
即可为使用了这一材质的面设定渲染阶段。如将材质名设为 mat1#exteriortranslucent
将给使用 mat1#exteriortranslucent
这一材质的所有面添加半透明支持。这对于没有 mtllib
时的情况也有效,届时会将 #
之前的内容作为贴图文件名称。
注意:请只在确实是半透明的表面(如窗户)上设置 ……translucent
属性。为保性能,NTE 默认情况下不精确处理半透明面之间的遮挡关系,多个半透明面之间的互相遮挡关系很多时候都会不正确。