资源
Turian 使用导入管线:你放入项目 assets/ 文件夹的文件是源文件。导入时,每个源文件被分配一个稳定的 GUID(存储在副文件 <file>.meta 中),并烹饪为 .cache/assets/ 下的运行时产物。发布的游戏从打包的 .oap 中读取这些产物,从不接触松散的 assets/ 文件夹。资源之间的引用(材质的纹理、MeshRenderer 的网格)以 GUID 形式存储,因此在重命名和移动时仍然有效。
导入模型(glTF / GLB / OBJ)
将 .gltf、.glb 或 .obj 放入 assets/ 会导入其几何体。对于 glTF/GLB,Turian 还会读取文件中的材质和纹理,并从中生成引擎资源——单个模型是一个源,会产生多个资源:
- 每个 glTF 材质对应一个
.material,将 glTF 金属粗糙度模型映射到内置 PBR 着色器(基础颜色、金属度、粗糙度、自发光 + 强度、法线缩放、遮蔽、透明度模式/阈值、双面 → 剔除); - 每个引用的图像对应一个纹理资源。
这些生成的资源记录在模型的 .meta 中,并在重新导入时保持其 GUID,因此场景引用保持有效。不支持的材质扩展会发出警告,但不会致命。
几何体在导入时烹饪为规范的二进制网格,因此运行时通过一个快速、格式无关的路径加载它——OBJ/glTF/cgltf 解析仅在编辑器中进行,从不在发布的游戏中进行。
编辑生成的子资源
在资源浏览器中选择一个导入的模型;检查器会在生成的资源下列出其生成的材质/纹理。单击一个材质打开并调整(例如其基础颜色)。编辑在重新导入时保持不变——导入器仅(重新)生成缺失的材质。完整的重新导入会清除缓存,从源重新生成所有内容。
节点层级和逐网格几何体(glTF/GLB)
glTF/GLB 文件的场景图——具名节点、父子变换,以及每个节点使用哪个网格 ——也会被导入,而不仅仅是材质和纹理。除了生成的材质之外,Turian 还会写入:
- 每个 glTF *网格(mesh)*对应一个网格子资源,拥有自己的子网格和名 称,与模型自身烹饪的产物(对于简单的单对象拖入,仍保持为整个文件展平 成一个网格,不变)分开保存;
- 一个 Hierarchy 子资源——一个 预制体, 每个 glTF 节点对应一个 GameObject,命名和定位都与源文件一致,每个携带 网格的节点都连接到其网格和生成的材质。
在生成的资源中,紧挨着模型的材质即可找到它;将其拖入场景视口——或右 键单击它并选择实例化到场景——即可像实例化任何其他预制体一样,一次性 带入整个具名层级。
目前只有 glTF/GLB 携带节点层级;OBJ 仍然作为没有子网格的单一展平网格导 入。蒙皮/骨骼绑定也不会被导入——绑定文件的关节节点会作为普通(不带动画 的)GameObject 导入。
导入设置
选择纹理或模型会显示导入设置面板:
- 图像 —— 纹理类型(默认 / 法线贴图 / 精灵 / UI / HDR)、色彩空间、Mipmap、压缩、滤镜、包裹、最大尺寸,以及(仅 DDS)用于 DirectX 惯例法线贴图的绿色通道翻转。
- 模型 —— 导入材质、导入动画、缩放因子。
- 字体 —— 默认大小。
设置存储在 .meta 中;应用会重新烹饪资源。
外部纹理 vs 内嵌纹理
- 外部图像(glTF 引用同级
.png/.jpg文件)成为普通的纹理资源,拥有自己的.meta——因此你可以像其他任何资源一样选择和交换它们。 - 内嵌图像(GLB 二进制块或 base64 数据 URI)在导入期间被提取为仅缓存纹理资源。
无论哪种方式,生成的材质都会通过 GUID 绑定每个贴图。常见格式(PNG、JPEG 等)被解码为 RGBA8。
纹理格式
| 格式 | 路径 |
|---|---|
| PNG / JPEG / BMP / TGA / WebP | 解码为 RGBA8(stb_image)。 |
KTX2(.ktx2) |
GPU 块格式直接上传——BCn 直通、Zstandard 解压、Basis Universal(ETC1S / UASTC)转码为 BC7。Mip 级别得以保留。 |
DDS(.dds) |
传统 FourCC(DXT1/DXT3/DXT5/ATI1/ATI2)和 DX10 扩展头,原样按块复制——BC1/BC3/BC4/BC5/BC7,不重新编码。Mip 级别得以保留;不支持立方体贴图/数组。 |
KTX2 支持位于独立、与引擎无关的 ktx2 模块中(包含供应商提供的 Basis Universal 转码器),嵌入在 loadTexture 后面,因此材质和导入器保持格式无关。DDS 由
engine/assets/DdsLoader.zig 解析和解码,该模块复用了 ktx2 模块的
Format/Level 类型,因此两种容器都能生成完全相同的 GPU 就绪形状。
由于传统 DDS FourCC 没有 sRGB 位,导入器的 Color Space(色彩空间)设置
会在导入时被固化:标记为 sRGB 的 DDS 会被重写为携带匹配 sRGB DXGI 格式的
DX10 扩展头(仅在需要时升级容器);启用 Flip Green Channel(翻转绿色
通道)的法线贴图会逐块无损翻转其 BC5 绿色通道,以匹配引擎的 Y 轴惯例。
PNG/JPEG 等格式的源文件总是被 stb_image 解码为线性 RGBA8,因此 Color
Space(色彩空间)为 sRGB 时也采用相同的方式烹饪:在导入时会在源字节前
添加一个很小的信封(envelope),加载器会在升级解码后纹理的 GPU 格式之前将
其剥离。Linear 不需要任何烹饪,因为它本来就与解码器的默认值一致。
由 glTF/FBX 材质引用的法线贴图、金属粗糙度贴图和遮蔽贴图,在其对应图像第一
次被导入时,会默认将该图像的 Color Space 设为 Linear(对于法线贴图,
还会将 Texture Type 设为 Normal Map)——此后的重新导入不会覆盖你已手动
更改的设置。
PBR 材质
.material 是一个小型 JSON 资源,通过 GUID 引用着色器,并存储该着色器暴露的参数值。内置的 PBR(金属粗糙度) 着色器暴露:
| 参数 | 类型 | 说明 |
|---|---|---|
base_color |
颜色 | 漫反射色调(RGBA) |
metallic、roughness |
标量 | 0–1 |
emissive、emissive_strength |
颜色 / 标量 | |
normal_scale、occlusion_strength |
标量 | |
alpha_cutoff |
标量 | 用于蒙版透明度 |
albedo_map、metallic_roughness_map、normal_map、emissive_map、occlusion_map |
纹理 | 通过 GUID 绑定 |
由于生成的材质是普通资源,你可以在检查器中编辑它,或者将网格切换到不同的材质而无需接触模型。当你将 MeshRenderer 的网格设置为模型且其材质仍为空时,Turian 会自动填充该模型的主要生成材质。
你也可以通过资源浏览器从头创建材质,包括内置预设(默认、金属、塑料、自发光、玻璃)。
多材质网格
单个网格可以携带许多子网格,每个都被标记了一个材质槽位。一个
MeshRenderer 每个槽位持有一个材质——其检查器中的 Material 列表每
个槽位显示一行(“Material 0”、“Material 1”……)——每个子网格都使用绑定
到其槽位的材质进行绘制。单位是槽位,而不是子网格:一个拥有数千个子网格
但共享少数几个材质的模型,只需要那少数几个槽位。这使得展平成一个网格的
整个场景(数百种材质)都能完整渲染,每个表面都拥有自己的 PBR 材质。
当你将 MeshRenderer 设置到一个模型上时,Turian 会自动为每个槽位填充为
其生成的材质;之后你可以单独替换任意一个槽位。
字体资源
将 .ttf 或 .otf 放入 assets/ 会将其注册为字体资源——与其他任何
资源一样,拥有 GUID、.meta、资源浏览器缩略图以及导入设置面板
(默认大小)。
选择字体会显示实时预览:Studio 会(每个会话一次,以 GUID 为键)将字体
的真实字节注册到 dvui,并以几种大小渲染实际的示例文本,旁边是使用 dvui
主题的默认正文字体设置的比较行——以便您在任何地方使用之前评估一款字体。
examples/basic-project/assets/fonts/ 附带了三款 SIL OFL 许可的字体
(Lora、Bebas Neue、Inconsolata——见其中的 ATTRIBUTION.md),它们因视觉
对比(衬线体、紧凑显示体、等宽体)而被选中,作为一个可运行的演示。
.uidoc 文本节点可以直接引用字体资源:将 style.font 设置为字体的 GUID
(并可选地设置 style.font_size,默认 24),它会优先于 style.font_style
的主题名称查找。字体的字节通过渲染器已用于图像的同一个以 GUID 为键的源
回调解析,然后每个会话向 dvui 注册一次——由 Studio 视口(编辑模式叠加层、
Play mode 以及 .uidoc 编辑器自身的预览)和已发布的游戏共同共享,因此
任何地方都不需要 #if EDITOR 风格的分支。
examples/basic-project/assets/ui.uidoc 的标题以这种方式使用 Bebas Neue,
作为一个可运行的示例。
设置整个文档(而非按节点)字体的 Theme 资源(issue #104 的史诗任务)被 列为后续的非阻塞工作。
示例
3d-model-materials 示例并排展示了三个对象:使用内置金属预设的 OBJ 立方体、作为 glTF(外部 .png 贴图)的 Khronos WaterBottle,以及作为 GLB(导入时提取的内嵌贴图)的同一个瓶子。其结构设计为可扩展到大型场景,如 Sponza 或 Bistro——将模型放入 assets/models/,打开项目,添加到场景中即可。
另请参阅组件参考了解 MeshRenderer 组件,以及项目设置了解引导场景。