DreamShaderLang
参数

Properties 属性

Properties 属性

属性

DreamShader » DreamShaderLang » 属性

一个声明块的段落,用于声明该块生成到其材质图中的参数节点、常量节点和 UE.* 内置节点。

声明位置.dsm、.dsf —— 位于 Shader、ShaderFunction、ShaderLayer、ShaderLayerBlend 内部
种类段落
生成图实际读取的那些声明所对应的节点
别名在 VirtualFunction 内部,Properties 是 Inputs 的同义词 —— 见说明

在 2.0 中,属性是一个 uniform(或一个 static const),其元数据写在 /// 行中 —— 见 DreamShaderLang 2.0;dsc migrate 会按这种方式重写一个段落。

语法概要

Properties [=]
{
    <property-declaration>…
    <group-scope>…
}
property-declaration := [ const ] <type-token> <name> [ = <default> ] [ [ <metadata> ] ] ;

group-scope          := Group( "<group-name>" ) { { <property-declaration> | <group-scope> }… } [ ; ]

在 property-declaration 中,[ … ] 围绕 <metadata> 的最内层一对是字面的 DreamShaderLang 标点;外层一对是表示「可选」的元语法。因此,带元数据块的声明形如 float Roughness = 0.5 [Group="Surface"];。

段落名与其 { … } 块之间的 = 是可选的语法糖 (自 1.5.0 起)。段落名按大小写不敏感匹配。段落结束 } 之后的 ; 是可选的,最后一条声明之前的 ; 也是可选的。

声明成员

成员必需形式说明
const否关键字生成常量节点而不是参数节点。大小写不限。(自 1.2.6 起)
<type-token>是token选择生成的节点类以及默认值语法。见类型 token。
<name>是标识符Graph 读取的标识符,并且 —— 除非 [ParameterName=…] 覆盖它 —— 也是材质参数名。
= <default>否字面量初始值。可接受的字面量语法由类型 token 决定,而不是由字面量的形状决定。
[ <metadata> ]否块分组、排序优先级、描述、滑块边界,以及任意反射的 UMaterialExpression 属性。见元数据。

解析顺序

(自 2.0.0 起) 声明从左到右逐个 token 读取:

步骤读取缺失或错误时
1可选的 const——
2类型:一个词,或带其 ( … ) 实参列表的 UE.<Function>DSH3250;在 const 之后为 DSH3251
3名称:一个标识符DSH3250
4在 = 之后,默认值:直到括号外出现 [ 或 ; 之前的每一个 token= 之后没有任何内容时为 DSH3254
5可选的 [ … ] 元数据块DSH3255
6;,或结束段落或分组的 }DSH3250

任意类型的空白都会分隔这些词,因此类型与名称之间用制表符也可以,而带空格实参列表的 UE.* 内置类型也会被读作一个类型:

UE.TexCoord(Index = 0) UV;      // type = UE.TexCoord(Index = 0), name = UV

[!NOTE] (自 2.0.0 起) 名称必须是标识符。1.x 只检查其非空,因此 Properties { float 1Bad = 0; } 能解析但不可达;现在 1Bad 是格式错误的数字 (DSH2105),并且该声明为 DSH3250。像 in 或 out 这样的关键字也不能作名称。

类型 token

可识别四个 token 家族,全部按大小写不敏感匹配。完整的目录位于各自的页面:

家族Token生成的节点参考
紧凑标量float half double int uint bool,以及各自带 1 后缀的版本(float1 …)UMaterialExpressionScalarParameter紧凑类型
紧凑向量float2..4 half2..4 double2..4 int2..4 uint2..4 bool2..4 vec2..4 ivec2..4 uvec2..4 bvec2..4UMaterialExpressionVectorParameter紧凑类型
紧凑纹理Texture2D TextureCube Texture2DArray Texture3D VolumeTexture —— 5 个 tokenUMaterialExpressionTextureObjectParameter紧凑类型
显式参数节点22 个 *Parameter / 采样器 token指定的 UMaterialExpression 子类参数节点
UE.<Function>[( … )]任意内置名称,带实参列表该内置的节点,或在给出 OutputType= 时使用反射节点UE 内置、UE.Expression

其他任何内容都是 DSH3252。在 22 个显式 token 中,有七个没有 2.0 形式,并且为 DSH3253 (自 2.0.0 起): DoubleVectorParameter、TextureCollectionParameter、CurveAtlasRowParameter、DynamicParameter、 FontSampleParameter、SpriteTextureSampler、SparseVolumeTextureObjectParameter。其余之中, ScalarParameter、VectorParameter、StaticBoolParameter 和 TextureObjectParameter 像紧凑 token 一样声明一个 参数;剩下的十一个在每次读取该属性时都会创建一个节点,与 1.x 一样。

[!NOTE] Properties token 集合与 Inputs / Outputs token 集合并不相同。 MaterialAttributes、Substrate 和 SamplerState 是有效的参数类型,但不是有效的 Properties 类型;矩阵拼写也不行。这里 StaticBool 读作 bool (自 2.0.0 起),因此它声明一个动态 bool 参数;静态开关参数是 StaticBoolParameter。各上下文的有效性矩阵见类型。

在 UE.* 内置属性上内联 = <default> 是 DSH3259 —— 其参数要放在圆括号内。

纹理默认值

纹理 token 的 = <default> 是一个资产引用。可接受四种写法,且四种都会 解析到同一个对象路径:

Texture2D A = Path(Game, "Textures/T_X");                      // root + relative path
Texture2D B = Path("/Game/Textures/T_X");                      // absolute path
Texture2D C = "/Game/Textures/T_X";                            // bare quoted absolute path
Texture2D D = Texture2D'/Game/Textures/T_X.T_X';               // Content Browser "Copy Reference" (since 1.9.0)

最后一种形式就是 Copy Reference 放到剪贴板上的内容,采用 /Script/Engine.Texture2D'…' 或较旧的 Texture2D'…' 拼写,并且可以裸粘贴、加 引号粘贴,或作为 Path(…) 的路径实参粘贴。引号前面的类会与 声明的纹理类型核对:把 Texture2D'…' 粘贴到 TextureSampleParameterVolume 会按 名称被拒绝(DSH1044;完全不是纹理的类为 DSH1043),而不是留到加载时失败。无法解析的引用为 DSH8271,解析后没有可加载内容的引用为 DSH8218。见 Path(…)。

const 属性

(自 1.2.6 起)

const 用常量节点替换参数节点,因此该值会被烘焙进材质, 不会出现在实例的参数列表中。

声明的类型生成的节点
标量UMaterialExpressionConstant
向量,2 个分量UMaterialExpressionConstant2Vector
向量,3 个分量UMaterialExpressionConstant3Vector
向量,4 个分量UMaterialExpressionConstant4Vector
纹理UMaterialExpressionTextureObject

规则:

  • const 可与紧凑的标量、向量和纹理 token 搭配使用,并且*(自 2.0.0 起)*可与 ScalarParameter、VectorParameter 和 TextureObjectParameter 搭配使用,它们按上述方式读取。与任何 其他参数节点 token 搭配时,它会被解析为 DSH3253。
  • 没有默认值的 const 为零。没有默认值的 const 纹理会生成一个 TextureObject 节点, 其自身没有写入任何纹理*(自 2.0.0 起)*:1.x 会回退到引擎该维度的默认资产, 并拒绝 Texture2DArray。
  • 常量的值由编译器决定:将其与其他常量组合的表达式可能会折叠 为一个常量节点。
  • const 向量在 Graph 中按其整个节点输出(索引 0)读取,而非 const 向量参数则通过与其分量数匹配的命名输出读取(R、RG、RGB、 RGBA)。请参阅在图(Graph)中读取参数。
Properties = {
    const float DebugScale = 1.0;                // UMaterialExpressionConstant
    float Strength         = 1.0;                // UMaterialExpressionScalarParameter
    vec3  Tint             = vec3(1.0, 1.0, 1.0);// UMaterialExpressionVectorParameter
}

Group("Name") { … } 作用域块

(自 1.5.0 起)

Group 作用域会将其名称印到它包含的每一个声明上,因此共享的分组不必 在每个声明的元数据中重复。

Properties {
    Group("Surface") {
        ScalarParameter Roughness = 0.5 [Slider(0, 1)];
        VectorParameter BaseColor = float4(1, 1, 1, 1);
    }
}

头部语法

规则详情
关键字Group,不区分大小写匹配
参数列表紧跟在关键字之后的 (,其中恰好包含一个双引号字符串,然后是 )
名称该字符串,去除首尾空白;它必须非空 —— DSH3260
主体{ … }
终止符闭合 } 之后的单个 ; 是可选的

Group(…) 是唯一可以在 Properties 中开启 { 的构造。任何其他 { 都是一个 诊断(DSH3250),而缺少 } 的分组会一直运行到文件末尾 (DSH2150)。

嵌套与 | 组合

作用域可以嵌套到任意深度。嵌套作用域的有效分组名称是外层名称、一个 |,以及 内层名称 —— 这正是 Unreal 自身用于 Group 属性的子类目语法:

Properties {
    Group("Surface") {
        float A = 0;                    // Group = "Surface"
        Group("Detail") {
            float B = 0;                // Group = "Surface|Detail"
            Group("Micro") {
                float C = 0;            // Group = "Surface|Detail|Micro"
            }
        }
    }
}

在分组名称中输入的字面 | 会原样传递,因此 Group("Manual|Literal") { … } 会精确产生 Manual|Literal。

继承优先级

继承的分组仅当该成员的元数据块既未输入 Group 也未输入 Category 时,才会应用到该成员。 声明上的显式键始终优先:

Group("Surface") {
    float A = 0;                        // Group = "Surface"     (inherited)
    float B = 0 [Group="Override"];     // Group = "Override"    (explicit wins)
    float C = 0 [Category="Other"];     // Group = "Other"       (Category is the alias)
}

自动 SortPriority

分组作用域的成员按声明顺序自动编号。

规则值
计数器起始值0
计数器步长10
计数器作用域同一个 Properties 区段中每个分组共享一个计数器,而不是每个分组一个
显式 SortPriority / Sort优先,并且不消耗槽位
未分组(顶层)声明从不自动编号,也从不分配分组
Properties {
    Group("Surface") {
        ScalarParameter A = 0.5;                    // SortPriority = 0
        VectorParameter B = float4(1, 1, 1, 1);     // SortPriority = 10
    }
    Group("Detail") {
        ScalarParameter C = 1.0 [SortPriority=99];  // SortPriority = 99, no slot consumed
        ScalarParameter D = 2.0;                    // SortPriority = 20  (counter continued)
    }
    ScalarParameter Loose = 3.0;                    // no group, no auto sort
}

[!NOTE] 计数器在每个 Properties 区段中初始化一次。一个块声明了两次 Properties 时, 第二个区段中的计数器会从 0 重新开始,因此两个区段中的两个分组可能最终 得到重叠的排序优先级。

当没有分组作用域且没有显式元数据提供值时,参数会得到 32,即引擎自身 对参数节点的默认值 —— 也是 1.x 保留的值。

元数据

末尾的 [ … ] 块与带类型参数的各节共享。其可识别的键为:

键别名值
GroupCategory字符串
DescriptionDesc、Tooltip字符串
SortPrioritySort整数 —— 否则 DSH3258
Slider(min, max)—不带 = 的简写;与 SliderMin + SliderMax 相同的范围 —— 格式错误或给出两次时为 DSH3257
ParameterName—字符串;覆盖材质参数名称
SamplerType—采样器类型;SAMPLERTYPE_ 前缀会被丢弃
其他任何内容—写入同名的反射 UMaterialExpression 属性

条目由 ; 或 , 分隔,键不区分大小写匹配:写入两次的键为 DSH3256。对标量参数之外的任何内容设置滑块范围都会被 忽略并给出警告 DSH7233。完整语法、反射 规则以及枚举值的拼写见 元数据。

排序与重复

  • 语句以 ; 结尾。读取器会跟踪 ()、[] 和 {},而字符串是一个 token,因此 Group 主体和方括号元数据块绝不会在错误的位置拆分语句。
  • 注释可以位于 token 之间的任何位置。
  • 各节可以在块内以任意顺序出现,重复的 Properties 节 会追加到前一节。在节级别没有“声明两次”诊断。
  • 声明顺序不影响 Graph 中的名称解析:Graph 会在块的每个 其他节之后读取,因此在其下方声明的属性仍然可见。参数在图首次读取它的地方构建, 并被之后的每次读取共享,而没有任何读取的属性不产生节点。十一个没有参数形式的参数节点 token 是例外:每次 读取都是它自己的节点,与 1.x 一样。
  • 声明顺序确实决定自动 SortPriority 计数器。
  • UE.* 属性在读取它的 Graph 主体头部成为一个值,仅在 主体读取它时构建,按声明顺序。
  • 在一个文件中声明两次的名称为 DSH4210。该检查 精确比较名称*(自 2.0.0 起)*;1.x 忽略大小写进行比较。

说明

  • Properties 在 VirtualFunction 里含义不同。 在那里它是 Inputs 的别名,使用带类型参数的语法(opt,没有 const,没有节点 token),而不是本页的声明语法。见 VirtualFunction。
  • property 节点落在哪里是 graph 布局 的事; Layout 区段可以钉住它们。
  • (自 2.0.0 起) 上表没有点名的每个元数据键都由反射写到节点上。在参数上,节点类没有的键会给出警告 DSH8210,值不会被写入 —— 1.x 会拒绝它, Group、SortPriority 和 Desc 除外;属性接受不了的值会给出 DSH8213。在没有参数形式的十一个参数节点 token 上,这些键是节点的参数, 未知的键会给出 DSH5213 —— 或者,当其值是数字时,给出信息 DSH5291,随后在构建出的节点没有该引脚时给出 DSH8212。
  • 重新生成会破坏对生成节点的手工编辑。见 重新生成。

诊断

每条诊断都带有它所针对的声明的行和列。

代码触发条件
DSH3250区段没有用 { 打开;语句没有类型和名字;声明没有以 ; 结束;一个不是 Group 作用域的 {
DSH3251const 后面没有类型
DSH3252类型既不是紧凑 token、不是参数节点 token,也不是 UE.*
DSH3253没有 2.0 形式的参数节点 token,或 const 后面跟着一个不能作常量的参数节点 token
DSH3254= 后面没有东西,或类型读不了的默认值:不是数字或 true / false 的标量、不是 name(a, b, c, d) 字面量的向量、不是 true / false 的静态开关
DSH3255未闭合的元数据块,或不是 Key = Value 的条目
DSH3256写了两次的元数据键
DSH3257格式错误的 Slider(…),或给了两次的滑块范围
DSH3258不是整数的 SortPriority
DSH3259未闭合的 UE.* 参数列表,或在 UE.* 属性之后写的默认值
DSH3260Group("")
DSH2150文件在区段或分组内结束
DSH1043、DSH1044纹理默认值的 Class'…' 外壳不是纹理,或不是声明的纹理类型
DSH4210声明了两次的名字
DSH7233警告:没有滑块的参数上有滑块范围
DSH8210警告:参数节点没有的元数据键
DSH8213节点属性接受不了的元数据值
DSH8218、DSH8271加载不了或解析不了的纹理默认值

完整列表见 诊断索引。

示例

Shader(Name="Materials/M_Surface", Root="Game")
{
    Properties {
        Group("Surface") {
            VectorParameter BaseColor = float4(0.8, 0.8, 0.8, 1.0);   // SortPriority 0
            ScalarParameter Roughness = 0.55 [Slider(0, 1)];          // SortPriority 10
            Group("Advanced") {
                ScalarParameter Metallic = 0.0;                       // Group "Surface|Advanced", 20
            }
        }

        Group("Textures") {
            TextureSampleParameter2D AlbedoMap = Path(Game, "Textures/T_White_Linear") [
                SamplerType="LinearColor";
                MipValueMode="None";
                AutomaticViewMipBias=true;
            ];                                                        // SortPriority 30
        }

        const float DebugScale = 1.0;                                 // ungrouped, not auto-sorted
        UE.TexCoord(Index = 0) UV;                                    // ungrouped
    }

    Outputs {
        float3 Color;
        float  Rough;
        float  Metal;

        Base.BaseColor  = Color;
        Base.Roughness  = Rough;
        Base.Metallic   = Metal;
    }

    Graph {
        float4 Albedo = AlbedoMap(Coordinates = UV);
        Color = Albedo.rgb * BaseColor.rgb * DebugScale;
        Rough = Roughness;
        Metal = Metallic;
    }
}

生成的参数组织:

Surface           SortPriority  0   BaseColor   VectorParameter
Surface           SortPriority 10   Roughness   ScalarParameter, slider 0..1
Surface|Advanced  SortPriority 20   Metallic    ScalarParameter
Textures          SortPriority 30   AlbedoMap   TextureSampleParameter2D

DebugScale  -> UMaterialExpressionConstant           not a parameter; ungrouped, not auto-sorted
UV          -> UMaterialExpressionTextureCoordinate  ungrouped, not auto-sorted

另见

本页目录