资产介绍

概述

资产指的是Dagor 引擎工具中使用的所有资源类型。

您可以在 application.blk文件中找到项目中支持的资产类型列表。该文件是配置工具与项目交互方式的关键资源。

assets{
  types{}
}

application.blk 文件中,资产目录的基本路径指定为 base:t=

资产主要分为三类:

  1. 编辑器专用资产: 这些是编辑器专用的资源,例如用于导出关卡。例如材质、预制件、样条类等。

  2. 游戏导出资产: 这些资源被导出到游戏中(由 application.blk 中的 export{} 块指示)。它们存储在游戏中的 .grp 文件中。通常情况下,出于性能考虑,关卡编辑器会使用导出的游戏资源。

  3. 纹理: 虽然这些纹理通常会导出到游戏中,但它们存储在.dxp.bin文件中。编辑器使用纹理缓存而不是导出纹理,这样就可以实时修改纹理。

资产格式和管理

游戏和工具的资产都存储在.blk文件中,有两种格式:

  • 现代格式<asset_name>.<className>.blk(例如,my_house.rendinst.blk)。

  • 传统格式<asset_name>.blk,其中资产类型必须在.blk文件中指定。

每个资产的.blk文件都包含该特定资源的导出程序所需的所有参数。每种类型的资源在游戏中都有自己的构建工具插件和专用代码。

在某些情况下,.blk文件中的说明非常少。例如,纹理资产可能只需要纹理名称(如果是 .dds 格式)。在其他情况下,例如特效,整个资产都定义在.blk文件中,而Asset Viewer则充当其编辑器。

大多数资产都没有专门的编辑工具。创建这些资产的主要方法是使用工具手动编辑和热加载。

然而,为了避免为每种简单的资产类型(如纹理、骨骼、动态模型)手动创建.blk文件,Dagor 支持一种高度灵活的虚拟资产创建系统–通过放置在资产目录中的 .folder.blk 文件来创建。

实际上,在 99.99% 的情况下,只需将纹理和模型放入相应的目录即可。许多规则,如 LOD(细节级别)切换距离和纹理转换规则,都将自动生成。

Note

所有资源名称必须唯一。如果资源在其类型内是唯一的,系统一般就能正常运行,但最好还是确保全局唯一的名称。

资产类型及其规则

纹理资产

纹理资产参数概述(所有参数均为可选参数,对于标准漫反射纹理 .dds,可能无需指定任何参数。对于 .tga 文件,通常需要两个参数: convert:b=yes, fmt:="DXT1|DXT5"):

contents{
  convert:b=yes; fmt:t="DXT1|DXT5"
  mipmapType:t=mipmapGenerate
  mipFilter:t="filterKaiser"; mipFilterAlpha:r=40; mipFilterStretch:r=2
  addrU:t="wrap"; addrV:t="wrap";
  swizzleARGB:t="RAG0"
  hqMip:i=3; mqMip:i=3; lqMip:i=4
  PC{
    hqMip:i=2; mqMip:i=2; lqMip:i=3;
  }
  gamma:r=1
  colorPadding:b=no
  // alphaCoverageThresMip9:i=200
  // alphaCoverage:b=no
  // rtMipGen:b=no
  // aniFunc:t="abs";
  // anisotropy:i=8
  addrU:t="wrap"; addrV:t="wrap";
}
  • convert:转换纹理(对于所有 .tga.psd 纹理必须使用)。

  • fmt:t: 指定要转换的格式(选项包括 DXT1DXT5ARGBL8A8L8L16)。

  • mipmapType:t: 生成 mipmap 的方法(mipmapGeneratemipmapUseExistingmipmapNone)。

  • mipFilter: 指定用于生成 mipmap 的过滤器(filterKaiser, filterBox, filterCubic)。

  • hqMipmqMiplqMip: 指定在高、中、低质量设置下使用的 mip 级别。

  • swizzleARGB: 指定如何旋转纹理通道。通常不需要。

  • gamma: 伽玛校正值(“1 ”用于法线贴图和遮罩,默认为 “2.2”)。

  • addrU, addrV: 纹理寻址模式(wrapclampborder)。

动态模型和渲染实例

lod{
  range:r=70; fname:t="$1.lod00.dag";
}
lod{
  range:r=200; fname:t="$1.lod01.dag";
}
lod{
  range:r=550; fname:t="$1.lod02.dag";
}
lod{
  range:r=4000; fname:t="$1.lod03.dag";
}
ref_skeleton:t="$1_skeleton"
texref_prefix:t="low_"
all_animated:b=yes
  • lod: LOD 参数。

    • range:r: LOD 距离。

    • fname:t: 可选文件名,默认为 $1.lod<lod_number>.dag

  • texref_prefix:t: 添加到模型中所有纹理引用的前缀。

  • ref_skeleton:t: 动态模型的引用骨架,是 Asset Viewer 中正确预览所必需的。

  • all_animated:b: 表示模型中的所有对象都应被视为动画对象,即拥有自己的矩阵。

复合动态模型

复合动态模型是由共享一个共同骨架的多个动态模型组成的结构。

下面是为复合模型创建 .skeleton.blk文件的规则,以一辆有多个炮塔和火炮选项的坦克为例:

name:t="tank_body.lod00.dag"
attachSubSkel{
  attach_to:t="bone_turret"
  skel_file:t="turret_a.lod00.dag"
  skel_node:t="bone_turret"
  attachSubSkel{
    attach_to:t="bone_gun_a"
    skel_file:t="gun_a.lod00.dag"
    skel_node:t="bone_gun_a"
  }
  attachSubSkel{
    attach_to:t="bone_gun_b"
    skel_file:t="gun_b.lod00.dag"
    skel_node:t="bone_gun_b"
    add_prefix:t="G1:"
  }
  attachSubSkel{
    attach_to:t="bone_gun_c"
    skel_file:t="gun_b.lod00.dag"
    skel_node:t="bone_gun_b"
    add_prefix:t="G2:"
  }
}
attachSubSkel{
  attach_to:t="bone_turret"
  skel_file:t="turret_b.lod00.dag"
  skel_node:t="bone_turret"
  add_prefix:t="T1:"
}
  • name:t: 父模型名称。

  • attachSubSkel{}: 用于添加动态模型的模块。

    • attach_to:t: 父骨架中用于链接附加动态模型的节点。

    • skel_file:t: 子模型文件名。

    • skel_node:t: 子模型骨架中要与父模型链接的节点。

    • add_prefix:t: 所有子模型节点的前缀。

在上面的.skeleton.blk文件中,由tank_body模型生成的骨架被扩展为turret_aturret_b炮塔,它们连接到bone_turret上。在turret_a上,bone_gun_abone_gun_bbone_gun_c分别连接着两门独特的火炮gun_agun_b。但是,gun_b 被两次附加到不同的骨骼上。

由于我们创建的是一个共享骨架,因此避免节点名称重复至关重要。为了解决这个问题,我们为每个重复的节点添加了一个唯一的前缀。bone_gun_b 的两个副本在层次结构中形成了不同的分支,它们的前缀分别为 G1G2。同样,turret_b中的节点也有T1前缀。

Important

  • 指定附加节点时,不要包含自动添加的前缀。

  • 如果一个子模型附加到一个与其骨骼名称相同的节点上,前一个节点就会从层次结构中移除。不会有重复的–不用担心。

虽然从理论上讲,您可以创建非常深的依赖关系层次结构,但简单的结构更易于管理。在添加新层次之前,一定要评估其必要性。

一个多级层次结构可能是这样的

name:t="papa.lod00.dag"
attachSubSkel{
  attach_to:t="bone_papa"
  skel_file:t="child.lod00.dag"
  skel_node:t="bone_child"
  add_prefix:t="layer01:"
  attachSubSkel{
    attach_to:t="bone_child"
    skel_file:t="child.lod00.dag"
    skel_node:t="bone_child"
    add_prefix:t="layer02:"
    attachSubSkel{
      attach_to:t="bone_child"
      skel_file:t="child.lod00.dag"
      skel_node:t="bone_child"
      add_prefix:t="layer03:"
      attachSubSkel{
        attach_to:t="bone_child"
        skel_file:t="child.lod00.dag"
        skel_node:t="bone_child"
        add_prefix:t="layer04:"
      }
    }
  }
}

该层次结构展示了一个父模型(papa.lod00.dag),并附加了多层子模型,每个子模型都有自己的前缀,以确保唯一性和正确的层次结构管理。