Version:

材质类型文件规范

材质类型文件(*.materialtype)采用书面 JSON 格式,包含以下元素。

description

提供材质类型作者的描述或评论。

version

表示材质类型的当前版本号。使用此材质类型创建的任何材质都会在其 materialTypeVersion字段中保存此值。

versionUpdates

为引用该 .materialtype旧版本的.material文件提供向后兼容性。本节包括一个更新步骤列表,可将材质数据从一个版本更新到下一个版本。每当作者对材质类型做出会破坏现有材质的改动(如重命名属性)时,他们可以递增version号(前面已讨论过),并在此处提供新版本更新说明。然后,任何加载旧版.material文件的系统都可以自动升级,使其与最新的材质类型兼容。

  • toVersion: 表示引入这些更改时的材质类型版本。更新步骤将应用于 materialTypeVersion 编号小于此值的任何材质。

  • actions: 应用此更新时要执行的操作列表。每个操作首先会有一个 op 参数,用于指示要执行的操作。根据使用的操作,还必须指定其他参数。可用的操作及其所需参数如下:

op参数 1说明参数 2说明
renamefrom旧的属性名称to新的属性名称
setValuename要设置的属性名称value新属性值,必须是给定属性的适当类型
注意:
要升级.material源文件以匹配最新版本的材质类型,请在材质编辑器中打开它,然后保存。

示例

    ...
    "version": 5,
    "versionUpdates": [
        {
            "toVersion": 4,
            "actions": [
                {"op": "rename", "from": "opacity.doubleSided", "to": "general.doubleSided"}
            ]
        },
        {
            "toVersion": 5,
            "actions": [
                {"op": "rename", "from": "irradiance.color", "to": "irradiance.manualColor"},
                {"op": "setValue", "name": "irradiance.irradianceColorSource", "value": "Manual"}
            ]
        }
    ],
    ...

propertyLayout

本节定义了 “材质编辑器 ”中可用的属性集,以及它们将连接到哪些着色器输入或着色器选项。属性按组排列,每个组可以包含其他组,形成一个层次结构。材质编辑器的属性检查器会相应地将属性组织到组面板中。

通常的做法是使用 $import 功能将属性组定义 “因子化 ”为单独的 JSON 文件。这样就可以在多个 .materialtype 文件中重复使用属性组。

  • propertyGroups: 属性组的顶层列表。每个组包含以下内容:
    • name: 该组的标识符。该值必须采用 C 风格格式,并且在同级组中是唯一的。
    • displayName: 该组的给定名称,将显示在 “材质编辑器 ”中。
    • description: 该组的指定描述,将作为工具提示出现在材质编辑器中。
    • shaderInputsPrefix: 该组中出现的任何着色器输入名称(如着色器常量或着色器图像)都将自动预置此值。这在使用 $import 将共享组定义包含在另一个组中时非常有用。
    • shaderOptionsPrefix: 任何出现在该组中的着色器选项名称都会自动预置该值。这在使用 $import 将共享组定义包含在另一个组中时非常有用。
    • properties: 定义将出现在该组中的属性列表。
      • name: 该属性的标识符。该值必须采用 C 风格格式,并且在同级属性中是唯一的。
      • displayName: 该属性在材质编辑器中的给定名称。
      • description: 该属性的指定描述,将作为工具提示出现在材质编辑器中。
      • visibility: 该属性的初始可见性。默认为Enabled。可能的值有:
        • Enabled
        • Disabled
        • Hidden
      • type: 该属性的数据类型。支持的类型包括:
        • Bool
        • Int
        • UInt
        • Float
        • Vector2
        • Vector3
        • Vector4
        • Color
        • Image
        • Enum
      • enumValues: 定义 Enum 类型属性可能值的名称列表。
      • enumIsUv: 如果 true,且 type 设置为 Enum,则使用 uvNameMap中的 UV 名称作为可能的枚举值。
      • defaultValue: 该属性的默认值。必须根据标准 JSON 序列化(参见 O3DE 数据类型的 JSON 序列化)使用适当的数据类型指定该值。如果没有提供缺省值,那么根据数据类型,缺省值将是 false, 0或空。
      • min: 用户可使用滑块或类似 UI widget 配置的属性最小值。可与 maxsoftMax 或两者结合使用。
      • max: 用户可以使用滑块或类似 UI widget 配置的属性的最大值。可与 minsoftMin 或两者结合使用。
      • softMin: 用户可使用滑块或类似 UI widget 配置的属性最小值。不过,用户也可以手动输入一个更小的值。可与 maxsoftMax 或两者结合使用。
      • softMax: 用户可使用滑块或类似 UI widget 配置的属性最大值。不过,用户也可以手动输入更大的值。可与 minsoftMin 或两者结合使用。
      • step: 表示滑块或类似 UI widget 使用的增量大小。
      • vectorLabels: 为 Vector 类型属性的元素提供标签列表。默认情况下,标签为 “X”、“Y”、“Z”、“W”。
      • connection: 定义将属性值传递给着色器的连接。每个连接都定义了连接的typename和可选的shaderIndex。连接是可选的,如果省略,则可通过材质函数将属性连接到着色器。
        • type: 进行哪种类型的连接:
          • ShaderInput - 连接到 SRG_PerMaterial ShaderResourceGroup中的着色器常量或着色器图像。
          • ShaderOption - 连接到着色器选项。
        • name: 要连接的着色器输入或着色器选项的名称。
        • shaderIndex: 要连接到 shaders列表中哪个着色器的索引。默认情况下,它会连接到所有具有此名称选项的着色器。
    • propertyGroups: 其他属性组可以嵌套在这个属性组中。
    • functors: 用于自定义处理该组和子组中属性的材质函数列表。所有属性引用、着色器输入名称和着色器选项名称都以该属性组为本地范围。例如,如果该组名为 “baseColor”(基色),并有一个属性 “textureMap”(纹理图),那么函数可以简单地将该属性引用为 “texture”(纹理),系统会自动将其解释为 “baseColor.texture”(基色.纹理)。同样,“shaderInputsPrefix”(着色器输入前缀)和 shaderOptionsPrefix(着色器选项前缀)也会自动应用。例如,如果 shaderInputsPrefix 是 “baseColor_”,而着色器有一个名为 “baseColor_tex ”的纹理输入,那么函数可以将纹理输入引用为简单的 “tex”,系统会自动将其转换为 “baseColor_tex”。有关材质函数的更多信息,请参阅下面的 functors 部分。

示例

...
    "propertyLayout": {
        "propertyGroups": [
            {
                "name": "iris", 
                "shaderInputsPrefix": "m_iris_",
                "shaderOptionsPrefix": "o_iris_",
                "displayName":  "Iris",
                "description":  "Material properties for the iris.",
                "propertyGroups": [
                    {
                        "$import": "MaterialInputs/BaseColorPropertyGroup.json"
                    },
                    {
                        "$import": "MaterialInputs/NormalPropertyGroup.json"
                    },
                    { 
                        "$import": "MaterialInputs/RoughnessPropertyGroup.json"
                    }
                ]
            },
            {
                "name": "sclera", 
                "shaderInputsPrefix": "m_sclera_",
                "shaderOptionsPrefix": "o_sclera_",
                "displayName":  "Sclera",
                "description":  "Material properties for the sclera.",
                "propertyGroups": [
                    {
                        "$import": "MaterialInputs/BaseColorPropertyGroup.json"
                    },
                    {
                        "$import": "MaterialInputs/NormalPropertyGroup.json"
                    },
                    { 
                        "$import": "MaterialInputs/RoughnessPropertyGroup.json"
                    }
                ]
            },
            {
                "name": "eye",
                "displayName": "Eye parameters",
                "description": "Properties to control eye-specific rendering behavior",
                "properties": [
                    {
                        "name": "irisDepth",
                        "displayName": "Iris Depth",
                        "description": "Distance from the object origin to the plane (XZ) where the iris lays.",
                        "type": "float",
                        "defaultValue": 0.48,
                        "min": 0.0,
                        "softMax": 1.0,
                        "connection": {
                            "type": "ShaderInput",
                            "name": "m_irisDepth"
                        }
                    },
                    {
                        "name": "irisRadius",
                        "displayName": "Iris Radius",
                        "description": "Radius of the iris. It extends the iris/sclera mask to get more samples from one or the other (no UV deformation/stretching).",
                        "type": "float",
                        "defaultValue": 0.2,
                        "min": 0.0,
                        "softMax": 0.5,
                        "connection": {
                            "type": "ShaderInput",
                            "name": "m_eyeIrisRadius"
                        }
                    },
                    ...
                ]
            },
            { 
                "name": "specularF0",
                "displayName": "Specular Reflectance f0",
                "description": "The constant f0 represents the specular reflectance at normal incidence (Fresnel 0 Angle). Used to adjust reflectance of non-metal surfaces.",
                "properties": [
                    {
                        "name": "factor",
                        "displayName": "Factor",
                        "description": "The default IOR is 1.5, which gives you 0.04 (4% of light reflected at 0 degree angle for dielectric materials). F0 values lie in the range 0-0.08, so that is why the default F0 slider is set on 0.5.",
                        "type": "Float",
                        "defaultValue": 0.5,
                        "min": 0.0,
                        "max": 1.0,
                        "connection": {
                            "type": "ShaderInput",
                            "name": "m_specularF0Factor"
                        }
                    },
                    {
                        "name": "textureMap",
                        "displayName": "Texture",
                        "description": "Texture for defining surface reflectance.",
                        "type": "Image",
                        "connection": {
                            "type": "ShaderInput",
                            "name": "m_specularF0Map"
                        }
                    },
                    {
                        "name": "useTexture",
                        "displayName": "Use Texture",
                        "description": "Whether to use the texture, or just default to the Factor value.",
                        "type": "Bool",
                        "defaultValue": true
                    },
                    {
                        "name": "textureMapUv",
                        "displayName": "UV",
                        "description": "Specular reflection map UV set",
                        "type": "Enum",
                        "enumIsUv": true,
                        "defaultValue": "Tiled",
                        "connection": {
                            "type": "ShaderInput",
                            "name": "m_specularF0MapUvIndex"
                        }
                    }
                ],
                "functors": [
                    {
                        "type": "UseTexture",
                        "args": {
                            "textureProperty": "textureMap",
                            "useTextureProperty": "useTexture",
                            "dependentProperties": ["textureMapUv"],
                            "shaderOption": "o_specularF0_useTexture"
                        }
                    }
                ]
            },
            { 
                "$import": "MaterialInputs/SubsurfaceAndTransmissionPropertyGroup.json"
            },
            { 
                "name": "general",
                "displayName": "General Settings",
                "description": "General settings.",
                "properties": [
                    {
                        "name": "applySpecularAA",
                        "displayName": "Apply Specular AA",
                        "description": "Whether to apply specular anti-aliasing in the shader.",
                        "type": "Bool",
                        "defaultValue": false,
                        "connection": {
                            "type": "ShaderOption",
                            "name": "o_applySpecularAA"
                        }
                    },
                    {
                        "name": "enableMultiScatterCompensation",
                        "displayName": "Multiscattering Compensation",
                        "description": "Whether to enable multiple scattering compensation.",
                        "type": "Bool",
                        "connection": {
                            "type": "ShaderOption",
                            "name": "o_enableMultiScatterCompensation"
                        }
                    }
                ]
            }
        ]
    },
...

version (已弃用)

propertyLayout部分中的版本号已不再使用,取而代之的是之前显示的 version 版本号。

groups (已弃用)

propertyGroupspropertyLayout 中)所取代,它可以支持在同一位置定义属性和组的任意数量的组级别。引擎仍可加载旧格式,但任何新的材质类型文件都应使用新格式。

注意:
旧版本的材质类型文件格式用独立的groups 和properties部分来组织propertyLayout`。这就造成了一些限制,例如将属性分组限制为只有一个级别。这样就很难找出可重复使用的属性组。

properties (已弃用)

这已被propertyGroups替代。相似的有 groups (已弃用)

shaders

用于渲染此类型材质的着色器文件(*.shader)的引用数组。默认情况下,所有着色器都已启用,但可以使用 functors 关闭它们。

每个着色器项目都包含以下值。

  • file: 着色器文件的路径。该路径必须与资产根目录或材质类型文件相对。
  • tag: 该着色器项目的唯一名称,可用于在材质类型定义的其他地方(如材质函数中)引用该着色器。它必须是一个 C 样式标识符。
  • options: 使用键/值对列表为该着色器中的任何选项设置初始值。

示例

在本例中,我们引用了 ShadowMap 和 DepthPass 着色器。

"shaders": [
    {
        "file": "../ShadowMap.shader",
        "tag": "shadowmap",
        "options": {
            "o_depthBiasMode": "DepthBiasMode::Auto"
        }
    },
    {
        "file": "../DepthPass.shader",
        "tag": "depth"
    },
    ...
]

functors

材质函数数组。每个函数都会读取材质属性值,执行一些逻辑或计算,并相应设置着色器输入。这些函数可以用 Lua 或 C++ 来定义。每个函数数据包含以下内容:

  • type: 函数类型的名称。可能的值有:
    • Lua - 用于自定义 Lua 脚本函数
    • 专用函数类型的名称(在 C++ 中定义)。
  • args: 一个对象,包含要发送给该函数的所有参数的键/值对。参数因函数类型而异。

引擎提供了几种核心函数类型,在此一一列举。

注意:
其他宝石或游戏项目可以添加更多的函数类型。请尝试搜索 “RegisterMaterialFunctor ”的源代码,以了解可能存在的其他类型。

Lua

该函数类型使用自定义 Lua 脚本运行。它是最灵活的函数类型,几乎可用于任何情况。不过,与其他函数类型相比,它的性能较差。

有关 Lua 脚本本身的详细信息,请参阅 Lua材质函数 API

参数:

  • file: 包含材质函数代码的 .lua 文件的路径。该路径必须相对于资产根目录或材质类型文件。
  • propertyNamePrefix: 函数中出现的任何属性名称都将自动预置该值。请注意,这仅适用于在材质类型顶层定义的函数。属性组中的函数将从属性组中获取前缀。
  • srgNamePrefix: 函数中出现的任何 ShaderResourceGroup 字段名称都将自动预置此值。请注意,这仅适用于在材质类型顶层定义的函数。属性组中的函数将从属性组中获取前缀。
  • optionsNamePrefix: 函数中出现的任何着色器选项名称都将自动预置此值。请注意,这仅适用于在材质类型顶层定义的函数。属性组中的函数将从属性组中获取前缀。

示例

    ...
    {
        "type": "Lua",
        "args": {
            "file": "Materials/Types/StandardPBR_Roughness.lua",
            "propertyNamePrefix": "layer2_roughness.",
            "srgNamePrefix": "m_layer2_",
            "optionsNamePrefix": "o_layer2_"
        }
    },
    ...

UseTexture

如果UseTexture shader option 属性为 false,或Image类型属性没有图像绑定,则将UseTexture shader option 设置为 false。

参数:

  • textureProperty: Image类型属性的名称。
  • useTextureProperty: bool类型属性的名称。如果纹理属性为空,该属性将被隐藏。
  • dependentProperties: (可选)在未使用纹理时无关的其他属性列表。当纹理为空或未使用时,这些属性将被隐藏或禁用。
  • shaderTags: (可选)如果提供,着色器选项将只在此着色器列表中设置。请参阅 Shaders 部分中的 tags
  • shaderOption: 要设置的使用纹理着色器选项的名称。

示例

    ...
    {
        "type": "UseTexture",
        "args": {
            "textureProperty": "baseColor.textureMap",
            "useTextureProperty": "baseColor.useTexture",
            "dependentProperties": ["baseColor.textureMapUv", "baseColor.textureBlendMode"],
            "shaderOption": "o_baseColor_useTexture"
        }
    },
    ...

Transform2D

读取用户友好的属性(如旋转和缩放),并将其转换为二维变换矩阵供着色器使用。

参数:

  • transformOrder: 表示旋转、平移和缩放顺序的字符串数组。建议始终使用 [ "Rotate", "Translate", "Scale" ]
  • centerProperty: Vector2 类型属性的名称。定义旋转和缩放的中心。
  • scaleProperty: float属性的名称。控制变换的整体比例。
  • scaleXProperty: float属性的名称。控制 X 比例。
  • scaleYProperty: float属性的名称。控制 Y 比例。
  • translateXProperty:float属性的名称。控制 X 平移。
  • translateYProperty: float属性的名称。控制 Y 平移。
  • rotateDegreesProperty: float属性的名称。控制旋转的度数。
  • float3x3ShaderInput: 用于最终变换矩阵的 float3x3 着色器常量的名称。
  • float3x3InverseShaderInput: (可选)用于最终变换矩阵逆变换的 float3x3 着色器常量的名称。某些着色器可能需要此常量,例如使用视差映射效果的着色器。

示例

    {
        "type": "Transform2D",
        "args": {
            "transformOrder": [ "Rotate", "Translate", "Scale" ],
            "centerProperty": "center",
            "scaleProperty": "scale",
            "scaleXProperty": "tileU",
            "scaleYProperty": "tileV",
            "translateXProperty": "offsetU",
            "translateYProperty": "offsetV",
            "rotateDegreesProperty": "rotateDegrees",
            "float3x3ShaderInput": "m_uvMatrix",
            "float3x3InverseShaderInput": "m_uvMatrixInverse"
        }
    }

ConvertEmissiveUnit

这是一个专门的函数,用于一组标准化的发射照明属性。它允许枚举属性选择光强度单位(尼特或 EV100),并相应地转换光强度属性的值。

参数:

  • intensityProperty: float 属性的名称。指定发射光的强度。
  • lightUnitProperty: Enum 类型属性的名称。表示无量纲值的单位。
  • shaderInput: 将接收最终强度值的 float 着色器常量的名称。假定单位为尼特。
  • ev100Index: 根据 lightUnitProperty 的定义,与 EV100 的枚举值相对应的整数值。
  • nitIndex: 根据 lightUnitProperty 的定义,与 nits 的枚举值相对应的整数值。
  • ev100MinMax: 由两个浮点数组成的数组,表示在 EV100 模式下运行时的最小和最大强度值。
  • nitMinMax: 由两个浮点数组成的数组,表示在 nits 模式下运行时的最小和最大强度值。

示例

    {
        "type": "ConvertEmissiveUnit",
        "args": {
            "intensityProperty": "intensity",
            "lightUnitProperty": "unit",
            "shaderInput": "m_emissiveIntensity",
            "ev100Index": 0,
            "nitIndex" : 1,
            "ev100MinMax": [-10, 20],
            "nitMinMax": [0.001, 100000.0]
        }
    },

HandleSubsurfaceScatteringParameters

这是一个专门的函数,用于控制表层下散射和透光特性的标准化属性集。请参阅 Skin.materialtype ,了解其用法示例。

示例

    {
        "type": "HandleSubsurfaceScatteringParameters",
        "args": {
            "mode": "subsurfaceScattering.transmissionMode",
            "scale": "subsurfaceScattering.transmissionScale",
            "power": "subsurfaceScattering.transmissionPower",
            "distortion": "subsurfaceScattering.transmissionDistortion",
            "attenuation": "subsurfaceScattering.transmissionAttenuation",
            "shrinkFactor": "subsurfaceScattering.shrinkFactor",
            "transmissionNdLBias": "subsurfaceScattering.transmissionNdLBias",
            "distanceAttenuation": "subsurfaceScattering.distanceAttenuation",
            "tintColor": "subsurfaceScattering.transmissionTint",
            "thickness": "subsurfaceScattering.thickness",
            "enabled": "subsurfaceScattering.enableSubsurfaceScattering",
            "scatterDistanceColor": "subsurfaceScattering.scatterColor",
            "scatterDistanceIntensity": "subsurfaceScattering.scatterDistance",
            "scatterDistanceShaderInput": "m_scatterDistance",
            "parametersShaderInput": "m_transmissionParams",
            "tintThickenssShaderInput": "m_transmissionTintThickness"
        }
    },

OverrideDrawList (已弃用)

由使用 Lua 函数的SetDrawListTagOverride函数取代。

注意:
在使用 Lua 函数类型之前,该函数用于覆盖着色器的绘制列表名称。

uvNameMap

这将默认标识符映射到网格 UV 流。加载网格时,运行时会尝试使用这些名称匹配输入几何体的 UV 流。

对于每个条目,键必须与用于 float2 顶点输入的语义相匹配。值应该是一个用户友好的名称,与流的预期目的一致,并与其他材质类型中类似流的名称一致。默认情况下,O3DE 中的所有核心材质类型都使用 TiledUnwrapped 这两个名称。Tiled 表示平铺,因此可以接受重叠的船体。Unwrapped(无包裹)表示用于光贴图和类似用途,因此在 UV 空间中不应该重叠船体。

示例

    "uvNameMap": {
        "UV0": "Tiled",
        "UV1": "Unwrapped"
    }