你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

配置模型转换参数

本文介绍如何为模型转换配置参数。

“设置”文件

如果名为 <modelName>.ConversionSettings.json 的文件位于输入模型 <modelName>.<ext> 旁边的输入容器中,则使用该文件为模型转换过程提供额外的配置。 例如,转换 box.gltf 时,将使用 box.ConversionSettings.json 为模型转换设置参数。

JSON 转换设置文件的内容应具有以下架构:

{
    "$schema" : "http://json-schema.org/schema#",
    "description" : "ARR ConversionSettings Schema",
    "type" : "object",
    "definitions" : 
    {
        "position_attribute" : {"type" : "string", "description" : "Destination format of the position attribute", "enum" : [ "32_32_32_FLOAT", "16_16_16_16_FLOAT" ]},
        "color_attribute" : {"type" : "string", "description" : "Destination format of the color attribute", "enum" : [ "NONE", "8_8_8_8_UNSIGNED_NORMALIZED" ]},
        "vector_attribute" : {"type" : "string", "description" : "Destination format of the normals, tangents and binormals attributes", "enum" : [ "NONE", "8_8_8_8_SIGNED_NORMALIZED", "16_16_16_16_FLOAT" ]},
        "texcoord_attribute" : {"type" : "string", "description" : "Destination format of the texture coordinates attribute", "enum" : [ "NONE", "32_32_FLOAT", "16_16_FLOAT" ]}
    },
    "properties" : 
    {
        "scaling" : { "type" : "number", "exclusiveMinimum" : 0, "default" : 1.0 },
        "recenterToOrigin" : { "type" : "boolean", "default" : false },
        "opaqueMaterialDefaultSidedness" : {" type" : "string", "enum" : [ "SingleSided", "DoubleSided" ], "default" : "DoubleSided" },
        "material-override" : { "type" : "string", "default" : "" },
        "gammaToLinearMaterial" : { "type" : "boolean", "default" : false },
        "gammaToLinearVertex" : { "type" : "boolean", "default" : false },
        "sceneGraphMode" : { "type" : "string", "enum" : [ "none", "static", "dynamic" ], "default" : "dynamic" },
        "generateCollisionMesh" : { "type" : "boolean", "default" : true },
        "unlitMaterials" : { "type" : "boolean", "default" : false },
        "deduplicateMaterials" : {"type" : "boolean", "default" : true },
        "fbxAssumeMetallic" : {"type" : "boolean", "default" : true },
        "axis" : {
            "type" : "array",
            "items" : {
                "type" : "string",
                "enum" : [ "default", "+x", "-x", "+y", "-y", "+z", "-z" ]
            },
            "minItems" : 3,
            "maxItems" : 3
        },
        "vertex" : {
            "type" : "object",
            "properties" : {
                "position" : { "$ref" : "#/definitions/position_attribute" },
                "color0" : { "$ref" : "#/definitions/color_attribute" },
                "color1" : { "$ref" : "#/definitions/color_attribute" },
                "normal" : { "$ref" : "#/definitions/vector_attribute" },
                "tangent" : { "$ref" : "#/definitions/vector_attribute" },
                "binormal" : { "$ref" : "#/definitions/vector_attribute" },
                "texcoord0" : { "$ref" : "#/definitions/texcoord_attribute" },
                "texcoord1" : { "$ref" : "#/definitions/texcoord_attribute" }
            },
            "additionalProperties" : false
        },
        "metadataKeys" : {
            "type" : "array",
            "items" : {
              "type" : "string"
            }
        }
    },
    "additionalProperties" : false
}

box.ConversionSettings.json 文件可能如以下示例所示:

{
    "scaling" : 0.01,
    "recenterToOrigin" : true,
    "material-override" : "box_materials_override.json"
}

用于转换三角网格和点云的架构是相同的。 但是,与三角网格转换相比,点云转换使用严格的特征子集。

三角网格的设置

转换三角网格(如从 .fbx 文件转换)时,上一部分所示的架构示例中的所有参数都会影响转换结果。 后续部分提供了对参数的详细说明。

几何参数

  • scaling:此参数统一缩放模型。 缩放可用于增大或缩小模型,例如用于在桌面上显示建筑模型。 当模型以米之外的单位定义时,缩放也很重要,因为渲染引擎预期的单位为米。 例如,如果模型是以厘米定义的,则使用比例 0.01 会以正确的大小渲染模型。 某些源数据格式(例如 .fbx 文件)提供单位缩放提示。 在这种情况下,转换会将模型隐式缩放为以米为单位。 源格式提供的隐式缩放将应用于 scaling 参数上。 最终缩放因子应用于场景图形节点的几何顶点和局部转换。 根实体转换的缩放比例保持不变。

    重要

    展示和快速入门可能会补偿任何转换时缩放,因为它们都有内置的自动缩放功能。 有关详细信息,请参阅故障排除指南

  • recenterToOrigin:此参数指出应对模型进行转换,使其边界框以原点为中心。 如果源模型离原点较远,则浮点精度问题可能导致渲染噪点。 在这种情况下,将模型居中可以解决问题。

  • opaqueMaterialDefaultSidedness:渲染引擎假定不透明材料是双面的。 如果特定模型不符合该假定,则应将此参数设置为 SingleSided。 有关详细信息,请参阅单侧渲染

删除重复材料

  • deduplicateMaterials:此参数可允许或禁止自动删除拥有相同属性和纹理的重复材料。 重复删除在处理材料替代后发生。 默认情况下启用筛选器功能。

  • 如果模型具有超过 65,535 个材料,即使在删除重复材料后,该服务也会尝试合并具有类似属性的材料。 最后的终极选项是,超出限制的任何材料将被红色错误材料替换。

下图显示了两个多维数据集,其中共 68,921 个彩色三角形。 左边的示例是在删除重复之前,有 68,921 个颜色材料。 右边的示例是在删除重复之后,有 64,000 个颜色材料。 材料数量限制为 65,535 个。 有关材料限制的详细信息,请参阅限制

显示两个多维数据集的 68,921 个彩色三角形和删除重复的效果的屏幕截图。

颜色空间参数

呈现引擎期待颜色值处于线性空间内。 如果使用伽马空间定义模型,则应将以下选项设置为 true

  • gammaToLinearMaterial:将材料颜色从伽玛空间转换为线性空间。
  • gammaToLinearVertex:将顶点颜色从伽玛空间转换为线性空间。

注意

对于 FBX、E57、PLY、LAS、LAZ 和 XYZ 文件,这些设置默认为 true。 对于所有其他文件格式,这些设置默认为 false

场景参数

  • sceneGraphMode:定义如何转换源文件中的场景图。
    • dynamic(默认值):文件中的所有对象都作为 API 中的实体公开,并可任意转换和重新设置父级。 在运行时,节点层次结构与源文件中的结构相同。
    • static:与 dynamic 类似,但场景图中的对象不能在运行时动态地重新成为其他对象的父级。 对于具有许多移动部件的动态模型(例如“爆炸视图”),dynamic 选项会生成一个更高效的模型来渲染,但 static 模式仍允许单个部件转换。 如果不需要动态重设父级,则 static 选项最适合具有多个单独部件的模型。
    • none:场景图折叠为一个对象。

每个模式具有不同的运行时性能。 在 dynamic 模式下,即使没有移动部件,性能开销也会随图形中实体的数量线性缩放。 仅当同时移动多个部件或大型子图时,才使用 dynamic 模式。 例如爆炸视图动画。

static模式还会导出完整的场景图。 空间查询将返回各个部件,并且可以通过状态重写来修改每个部件。 在此模式下,每个对象的运行时开销可忽略不计。 此模式适用于下面的大型场景:需要按对象检查,偶尔对单个部件进行转换更改,但不重新设置对象父级。

none 模式的运行时开销最小,并且加载时间也稍微快一些。 在此模式下无法检查或转换单个对象。 用例可以是不以有意义场景图开始的摄影测量模型。

提示

许多应用程序会加载多个模型。 应根据每个模型的使用方式来优化转换参数。 例如,如果想要显示汽车模型,让用户能够详细剖析和检查,则首先使用 dynamic 模式来转换。 但是,如果还想将汽车放在展厅环境中,则可以在将 sceneGraphMode 设置为 static 甚至转换为 none 的情况下转换该模型。

物理学参数

  • generateCollisionMesh:如果需要支持在模型上进行空间查询,则必须启用此选项。 冲突网格生成不会增加额外的转换时间,也不会增加输出文件大小。 具有冲突网格的模型的加载时间和运行时成本仅稍高一点。 除非有特定原因需从空间查询中排除模型,否则可以将此标志保留为默认情况(启用)。

未打光材料

  • unlitMaterials:默认情况下,转换会创建基于物理的渲染 (PBR) 材料。 设置此选项后,转换器会将所有材料视为颜色材料。 如果你拥有已包含灯光的数据(如通过摄影测量创建的模型),则此选项允许快速对所有材料强制执行正确的转换。 你无需单独重写每个材料

从早期 FBX 格式和 Phong 材料模型转换

  • fbxAssumeMetallic:较早版本的 FBX 格式使用 Phong 材料模型定义其材料。 转换过程必须推断这些材料如何映射到渲染器的 PBR 模型。 这种映射的效果通常很好,但当材料没有纹理、高反射值和非灰返照色时,可能会出现模棱两可的情况。 在这种情况下,转换必须三选一:优先考虑高反射值、定义反射性强的金属材料使返照色消失,或者通过定义类似于光泽有色塑料的材料优先考虑返照色。 默认情况下,存在歧义时,则转换过程假定高反射值表示金属材料。 可以将此参数设置为 false 以获得相反的效果。

坐标系统替代

  • axis:使用此参数替代坐标系单位向量。 默认值有 ["+x", "+y", "+z"]。 理论上,FBX 格式具有标头,标头中定义了这些向量,转换使用该信息来转换场景。 glTF 格式也定义固定坐标系。 在实践中,某些资产的标头中包含不正确的信息,或者使用不同的坐标系约定保存。 此选项可用于替代坐标系统以进行补偿。 例如:"axis" : ["+x", "+z", "-y"] 交换 Z 轴和 Y 轴,并通过反转 Y 轴方向来保持坐标系的旋向。

节点元数据

  • metadataKeys:使用此参数指定要保留在转换结果中的节点元数据属性的键。 可以指定精确键或通配符键。 通配符键的格式为 ABC*,可与任何以 ABC 开头的键匹配。 支持的元数据值类型为 boolintfloatstring

    对于 GLTF 文件,此数据来自节点上的 extras 对象。 对于 FBX 文件,此数据来自 Properties70 上的 Model nodes 数据。 有关详细信息,请参阅 3D 资产工具的文档。

加载启用了元数据的模型时,可以通过异步 QueryMetadataAsync 函数检索特定实体的元数据条目列表。

顶点格式

可以调整网格的顶点格式,通过损失精度来节省内存。 如果模型内存占用较低,你可以加载更大的模型或实现更好的性能。 但是,根据具体数据,格式错误可能会显著影响渲染质量。

注意

如果模型不再适合内存,或者你想通过优化获得最佳性能,则更改顶点格式应是最后的终极选项。 更改很容易引入渲染噪点,包括明显和细微的噪点。 除非你知道应该注意什么,否则不应更改默认值。

可以进行以下调整:

  • 显式包含或排除特定数据流。
  • 减少数据流的准确性以减少内存占用。

JSON 文件中的以下 vertex 部分是可选的。 对于未显式指定的每个部分,转换服务将回退到其默认设置。

{
    ...
    "vertex" : {
        "position"  : "32_32_32_FLOAT",
        "color0"    : "NONE",
        "color1"    : "NONE",
        "normal"    : "NONE",
        "tangent"   : "NONE",
        "binormal"  : "NONE",
        "texcoord0" : "32_32_FLOAT",
        "texcoord1" : "NONE"
    },
    ...
}

通过将组件强制为 NONE,可以保证输出网格没有各自的流。

每个顶点流的组件格式

下表描述了各自组件允许的格式:

顶点组件 支持的格式 材料中的使用情况
position 32_32_32_FLOAT默认)、16_16_16_16_FLOAT 顶点位置。 必须始终存在。
color0 8_8_8_8_UNSIGNED_NORMALIZED默认)、NONE 顶点颜色。 请参见颜色材料PBR 材料中的 useVertexColor 属性,以及颜色材料中的 vertexMix 属性。
color1 8_8_8_8_UNSIGNED_NORMALIZEDNONE默认 未使用。 保留默认值 NONE
normal 8_8_8_8_SIGNED_NORMALIZED默认)、16_16_16_16_FLOATNONE 用于 PBR 材料中的照明。
tangent 8_8_8_8_SIGNED_NORMALIZED默认)、16_16_16_16_FLOATNONE 用于使用 PBR 材料中的法线贴图进行照明。
binormal 8_8_8_8_SIGNED_NORMALIZED默认)、16_16_16_16_FLOATNONE 用于使用 PBR 材料中的法线贴图进行照明。
texcoord0 32_32_FLOAT默认)、16_16_FLOATNONE 纹理坐标的第一个槽。 单个纹理(例如反照率,法线贴图等等)可以使用源文件中定义的插槽 0 或 1。
texcoord1 32_32_FLOAT默认)、16_16_FLOATNONE 纹理坐标的第二个槽。 单个纹理(例如反照率,法线贴图等等)可以使用源文件中定义的插槽 0 或 1。

支持的组件格式

下表描述了受支持组件格式的内存占用情况:

格式 说明 每个顶点的字节数
32_32_FLOAT 双组件全浮点精度 8
16_16_FLOAT 双组件半浮点精度 4
32_32_32_FLOAT 三组件全浮点精度 12
16_16_16_16_FLOAT 四组件半浮点精度 8
8_8_8_8_UNSIGNED_NORMALIZED 四组件字节,规范化为 [0; 1] 范围 4
8_8_8_8_SIGNED_NORMALIZED 四组件字节,规范化为 [-1; 1] 范围 4

组件格式更改的最佳做法

  • position:降低的准确度够用的情况很罕见。 16_16_16_16_FLOAT 会引入明显的量化噪点,即使对于小型模型也是如此。
  • normaltangentbinormal:通常,要一起更改这些值。 除非存在由正常量化而导致的明显发光点,否则没有理由提高其准确度。 但在某些情况下,可将这些组件设置为 NONE
    • 仅当应为模型中至少一种材料打光时,才需要 normaltangentbinormal。 在 Azure 远程渲染中,每当模型上使用 PBR 材料时,都会出现这种情况。
    • 仅当有已打光的材料使用普通映射纹理时,才需要 tangentbinormal
  • texcoord0texcoord1:如果纹理坐标的值保持在 [0; 1] 范围内,并且被强调纹理的最大大小为 2,048 × 2,048 像素,则纹理坐标可以使用降低的准确度 (16_16_FLOAT)。 如果超出这些限制,纹理映射的质量就会降低。

示例

假设你有一个摄影测量模型,其纹理中融入了照明。 要呈现该模型,只需要顶点位置和纹理坐标。

默认情况下,转换器必须假设你在某个时间可能想在模型上使用 PBR 材料,因此它将为你生成 normaltangentbinormal 数据。 因此,每个顶点的内存使用量为 position(12 字节)+ texcoord0(8 字节)+ normal(4 字节)+ tangent(4 字节)+ binormal(4 字节)= 32 字节。 这种类型的大型模型很容易拥有数百万个顶点,导致模型可能占用数 GB 的内存。 如此大量的数据会影响性能,甚至可能耗尽内存。

如果知道永远不需要对模型进行动态照明,并且知道所有纹理坐标都在 [0; 1] 范围内,就可以将 normaltangentbinormal 设置为 NONE,并将 texcoord0 设置为半精度 (16_16_FLOAT),从而使每个顶点仅占用 16 个字节。 当网格数据被切成一半时,可以加载更大的模型,并且性能可能会得到改善。

点云的设置

转换点云后,仅使用架构中的一小部分属性。 除非指定其他属性,否则将忽略其他属性。

会影响点云转换的属性包括:

  • scaling:与三角网格的含义相同。
  • recenterToOrigin:与三角网格的含义相同。
  • axis:与三角网格的含义相同。 默认值是 ["+x", "+y", "+z"],但与渲染器自己的坐标系相比,大多数点云数据都会旋转。 为了补偿,在大多数情况下 ["+x", "+z", "-y"] 修复旋转。
  • gammaToLinearVertex:类似于三角网格,此标志指示是否应将点颜色从伽玛空间转换为线性空间。 点云格式(E57、PLY、LAS、LAZ 和 XYZ 文件)的默认值为 true
  • generateCollisionMesh:与三角网格类似,若要支持空间查询,必须启用此标志。

内存优化

已加载内容对内存的消耗可能会成为渲染系统的瓶颈。 如果内存负载过大,则可能影响渲染性能或导致模型完全不加载。 本段落讨论了一些用于降低内存占用量的重要策略。

注意

以下优化适用于三角网格。 无法通过配置转换设置来优化点云的输出。

实例化

在实例化中,网格将重复使用具有不同空间转换的部件,而不是引用其自己的唯一几何图形的每个部件。 实例化对内存占用有重大影响。

实例化示例用例可以是引擎模型中的螺丝,也可以是体系结构模型中的椅子。

注意

实例化可以显著降低内存消耗(因此缩短加载时间),但对渲染性能的提升作用微乎其微。

如果源文件中已相应标记了部件,则转换服务不会遵循实例化。 但是,转换不会对网格数据进行额外的深入分析来识别可重用的部件。 内容创建工具及其导出管道是正确进行实例化设置的决定性条件。

在转换期间测试实例信息是否已保留的一种简单方法是查看输出统计信息。 具体而言,请检查 numMeshPartsInstanced 值。 如果 numMeshPartsInstanced 的值大于零,多个实例将共享网格。

示例:3DS Max 中的实例化设置

Autodesk 3DS Max 具有不同的对象克隆模式,这些模式称为“复制”、“实例”和“引用”。 这些模式在导出的 .fbx 文件中以不同的方式进行实例化。

显示使用 Autodesk 3DS Max 克隆对象的示例的屏幕截图。

  • 复制:在此模式下,将克隆网格,因此不会使用实例化 (numMeshPartsInstanced = 0)。
  • 实例:两个对象共享同一个网格,因此会使用实例化 (numMeshPartsInstanced = 1)。
  • 引用:可将不同修饰符应用于几何图形,因此导出程序选择传统方法,而不使用实例化 (numMeshPartsInstanced = 0)。

基于深度的组合模式

如果内存占用较多,请使用基于深度的组合模式来配置渲染器。 在此模式下,GPU 有效负载分布于多个 GPU。

减小顶点大小

组件格式更改的最佳做法所述,调整顶点格式可以减少内存占用。 但是,此选项应该作为最终手段。

纹理大小

根据情况的类型,纹理数据量可能超出网格数据所用的内存量。 摄影测量模型是候选项。 转换配置不支持自动纵向缩减纹理。 如有必要,必须在客户端预处理步骤中完成纹理缩放。 但转换步骤确实选择了合适的纹理压缩格式

  • 不透明颜色纹理的 BC1 文件格式
  • 具有 alpha 通道的源颜色纹理的 BC7 文件格式

由于 BC7 文件格式的内存占用是 BC1 文件格式的两倍,因此请务必确保输入纹理不提供不必要的 alpha 通道。

典型用例

为特定用例找到适当的导入设置可能是一个枯燥的过程。 另一方面,转换设置可能对运行时性能产生严重影响。

某些特定用例类符合特定的优化条件。 以下部分描述了一些示例。

用例:体系结构可视化或大型户外地图

对于涉及建筑可视化或大型户外地图的情况,请考虑以下因素:

  • 这些类型的场景往往是静态的。 它们不需要可移动部件。 因此,可以将 sceneGraphMode 设置为 static 甚至 none,并提升运行时性能。 在 static 模式下,场景的根节点仍可移动、旋转和缩放。 例如,它可以动态切换为 1:1 缩放(对于第一人称视图)或桌面视图。

  • 如果应用程序不使用剪切平面,则应关闭 opaqueMaterialDefaultSidedness 标志。 性能提升通常为 20% 到 30%。 你仍然可以使用剪切平面,但当你查看对象的内部部件时,不会有背面,这似乎不合乎直觉。 有关详细信息,请参阅单侧渲染

用例:摄影测量模型

渲染摄影测量模型时,通常不需要场景图。 在此情况中,可以选择将 sceneGraphMode 设置为 none。 由于这些模型很少包含复杂的场景图,因此选择此选项的效果可能微不足道。 由于已将光照融入纹理,因此不需要动态照明。 在本方案中:

  • unlitMaterials 标志设置为 true以将所有材料转换为未打光有色材料
  • 从顶点格式中删除不需要的数据。 请参阅前面的示例

用例:微型计算机和其他内容的可视化效果

在这些用例中,模型通常很小,但细节丰富。 渲染器进行了大量优化,可以很好地处理这些情况。 但是,以上用例中描述的大多数优化在这里并不适用。 优化包括:

  • 各个部件应是可选择且可移动的,因此必须将 sceneGraphMode 设置为 dynamic
  • 打光通常是应用程序不可分割的一部分,因此必须生成冲突网格。
  • 启用 opaqueMaterialDefaultSidedness 标志时,剪切平面看起来更好。

已弃用的功能

仍支持使用非特定于模型的 conversionSettings.json 文件名来设置模型转换参数,但此方法已弃用。 请改用特定于模型的 <modelName>.ConversionSettings.json 文件名。

仍支持使用 material-override 设置来标识转换设置文件中的材料替代文件,但该方法已弃用。 请改用特定于模型的 <modelName>.MaterialOverrides.json 文件名。

后续步骤