DreamShaderLang
插件参考Graph

构造函数

构造函数

构造函数

DreamShader » 图 » 构造函数

以标量或向量类型命名的调用语法表达式,用其参数构建该宽度的值。

声明于.dsm、.dsf — 在 Graph { … } 主体内、Outputs 绑定表达式中,或 Outputs 声明默认值中
种类表达式,调用形式
生成UMaterialExpressionAppendVector(第一个参数之后的每个参数一个),或者当所有参数都为常量时生成一个 UMaterialExpressionConstant / Constant2Vector / Constant3Vector / Constant4Vector;在直通和广播情形下不生成任何内容

概要

<constructor-call> := <constructor-name> ( <expression> [ , <expression> ] … )

命名参数会被拒绝。花括号初始化器 正是 构造函数调用:vec3 rgb = {r, g, b}; 会被重写为 vec3(r, g, b) 并遵守本页的所有规则。

解析器将构造函数名称读取为类型 (自 2.0.0 起):该调用不会进入函数查找, 绑定器会像检查 .dss 构造函数那样检查它。

构造函数名称

34 个名称,全部不区分大小写地匹配(FLOAT3(…) 也可用)。分量数是名称末尾的 数字;没有数字,或数字为 1 的名称是标量。

名称分量种类家族
float1floatHLSL float
float11floatHLSL float
float22floatHLSL float
float33floatHLSL float
float44floatHLSL float
half1halfHLSL half — 行为与 float 相同
half11halfHLSL half
half22halfHLSL half
half33halfHLSL half
half44halfHLSL half
vec22floatGLSL float 向量
vec33floatGLSL float 向量
vec44floatGLSL float 向量
int1intHLSL 有符号整数
int22intHLSL 有符号整数
int33intHLSL 有符号整数
int44intHLSL 有符号整数
ivec22intGLSL 有符号整数向量
ivec33intGLSL 有符号整数向量
ivec44intGLSL 有符号整数向量
uint1uintHLSL 无符号整数
uint22uintHLSL 无符号整数
uint33uintHLSL 无符号整数
uint44uintHLSL 无符号整数
uvec22uintGLSL 无符号整数向量
uvec33uintGLSL 无符号整数向量
uvec44uintGLSL 无符号整数向量
bool1boolHLSL 布尔
bool22boolHLSL 布尔
bool33boolHLSL 布尔
bool44boolHLSL 布尔
bvec22boolGLSL 布尔向量
bvec33boolGLSL 布尔向量
bvec44boolGLSL 布尔向量

(自 2.0.0 起) 解析器接受 HLSL 类型语法中的每种拼写,不区分大小写,因此还有少数 名称也是构造函数:

名称分量备注
int1、uint1、bool11HLSL 中标量的拼写,正如 float1 一样
double、double1 … double41–4种类为 double;在图中像每个数字一样是 float
StaticBool1读取为 bool,与在声明中一样
float2x2 … float4x4、mat2、mat3、mat4(以及其他家族的 NxM)—矩阵,图没有对应的值:DSH4361

不存在的名称

不存在原因
vec1、ivec1、uvec1、bvec1GLSL 家族从 2 开始
hvec2、hvec3、hvec4没有 GLSL half 家族
dvec2、dvec3、dvec4没有 GLSL double 家族
Scalar、Vector、Color已移除的类型别名;见 类型

上述每个名称都作为普通标识符进行词法分析,并且由于它不是类型,会落到 函数查找 — DSH4208,除非声明了该名称的函数。

MaterialAttributes、Substrate、纹理类型和 SamplerState 也是类型名称,但无法 构造它们的任何值:Texture2D(…) 是 DSH4223。

[!WARNING] 构造函数名称会遮蔽一切。 构造函数名称在解析调用时就被读取为类型 — 早于对 UE.* 内置函数、Substrate.* 内置函数、数学内置函数、参数以及所有用户定义的查找。一个名为 float3、int、bool4、vec2(或表中任何其他名称)的 Function、GraphFunction、ShaderFunction 或 VirtualFunction 可以在没有诊断的情况下声明, 但永远无法被调用 — 每个调用点都会构建一个构造函数。见 名称解析。

整数构造函数

整数名称为 int、int1..4、ivec2..4、uint、uint1..4 和 uvec2..4。对编译器而言,它们的结果 是 int 或 uint 值。

该种类只做一件事:当两个操作数都是整数构造函数调用时,/ 会被拒绝(DSH4243),与 1.x 中一样。它不执行截断、不舍入, 也不做范围限制 — 整数构造函数生成的浮点值图与其 float 对应物相同,而 int(7.9) 为 7.9。见 整数除法。

该种类来自构造函数自身的名称,因此用非整数构造函数包裹会清除它: float(int(7)) 是 float。

参数规则

先检查调用及其参数;每个失败的检查都会被报告。

#条件行为
1任何参数被命名(float3(x = 1.0))DSH4225
2完全没有参数(float3())DSH4221
3某个参数不是数字或 bool — 纹理对象、MaterialAttributes 或 Substrate 值 — 或者是矩阵DSH4226

然后,令 N 为构造函数的分量数:

#情况行为创建的节点
4恰好一个参数,且带有 N 个分量(对于 N == 1,则为标量)该参数被原样返回;只有它的种类发生变化无
5N > 1,恰好一个参数,且该参数为标量广播:标量被连接到读取该值的位置,材质节点复制它 (自 2.0.0 起;1.x 构建了一条 AppendVector 链)无;当标量为常量时创建一个 ConstantNVector
6其他情况各参数的分量数之和必须恰好等于 N第一个参数之后的每个参数各一个 AppendVector
7总和不等于 NDSH4222—

分量打包

规则 6 是通道从左到右的简单串联——只要总数精确,混合宽度的参数就是合法的。

调用总数有效结果
float4(rgb, 1.0)3 + 1是float4
float4(uv, uv)2 + 2是float4
float3(x, yz)1 + 2是float3
float4(x, y, z, w)1×4是float4
vec3(0.5)标量广播(规则 5)是(0.5, 0.5, 0.5)
float3(rgba)4否DSH4222
float3(uv)2否DSH4222
float(rgb)3否DSH4222
float3()0否DSH4221

[!NOTE] 构造函数从不收窄,在 1.x 源码中也是如此。float3(rgba) 是错误,而不是截断;请编写 rgba.rgb。收窄只发生在转换位置——参见 转换。加宽只从标量发生(规则 5); float3(uv) 不会补零。

常量折叠

当每个参数都是常量时,整个调用是一个常量节点,而不是 N 个 Constant 节点加上 AppendVector 个节点:一个持有这些值的 Constant / Constant2Vector / Constant3Vector / Constant4Vector。常量是数字字面量、其取负形式、一个 const 属性、持有常量的变量,或对常量的任何算术运算:折叠过程会折叠 操作数全为常量的运算符、构造函数和 swizzle (自 2.0.0 起)。

编写折叠为
vec2(0.5, 1.0)Constant2Vector(0.5, 1.0)
vec3(0.5)Constant3Vector(0.5, 0.5, 0.5) — 广播也会折叠
float4(1.0, 2.0, 3.0, -1.0)Constant4Vector(1, 2, 3, -1)
int3(1, 2, 3)Constant3Vector(1, 2, 3) (自 2.0.0 起);对编译器而言该值仍为 int3
vec3(K, 0.0, 0.0)当 K 是参数时不折叠——两个 AppendVector 节点

每个值都具有其类型的宽度;折叠后的构造函数没有自己的宽度,不会 覆盖声明 (自 2.0.0 起)。参见 转换。

相等的常量是同一个节点:写入五次的 vec3(0.5) 只产生一个 Constant3Vector。参见 节点复用。

说明

  • 规则 4 不创建任何节点。float3(SomeFloat3) 是空操作包装;float3(SomeInt3) 只 将种类改为 float。
  • 构造函数调用是普通后缀表达式,可以进行 swizzle:vec4(uv, 0, 1).xy。
  • 空主体的花括号初始化器(float3 v = {};)根本不会到达构造函数——它 产生该类型的零值。参见 声明。
  • 不支持嵌套花括号初始化器:float4 m = {{1,2},{3,4}}; 会被重写为 float4({1,2},{3,4}),而作为参数的花括号列表是 DSH2214。
  • 构造函数上的输出选择器(Output=、OutputIndex=) DSH5253。

诊断

代码触发条件
DSH4225任何 name = value 参数。
DSH4221没有参数的构造函数。
DSH4226参数为纹理对象、MaterialAttributes 或 Substrate 值,或矩阵。
DSH4222参数宽度之和不等于构造函数的宽度,且调用并非单个标量。
DSH4223没有构造函数的类型:MaterialAttributes、Substrate、纹理类型、SamplerState。
DSH4361矩阵构造函数:图中没有矩阵值。
DSH2214嵌套在花括号初始化器中的花括号列表。
DSH5253构造函数上的输出选择器。
DSH4208拼写错误的构造函数(vec1、float5)会落入函数查找。
DSH8214发射器无法创建 AppendVector 或常量节点。

示例

Shader(Name="Docs/M_Constructors", Root="Game")
{
    Properties { ScalarParameter K = 0.5; }
    Settings   { Domain = "Surface"; ShadingModel = "Unlit"; BlendMode = "Opaque"; }
    Outputs    { vec3 Color; Base.EmissiveColor = Color; }

    Graph {
        float  a    = frac(K * 3.0);
        vec3   grey = vec3(a);              // rule 5: scalar broadcast, no node
        vec3   tint = vec3(0.2, 0.4, 0.8);  // constant-folded to Constant3Vector
        vec2   uv   = float2(a, 1.0);       // rule 6: 1 + 1 packing
        Color = tint * grey + float3(uv, 0.0);   // rule 6: 2 + 1 packing
    }
}

生成的节点:

ScalarParameter K
Constant(3.0), Multiply, Frac                      -> a
(no node)                                          -> vec3(a): `a` is wired where grey is read
Constant3Vector(0.2, 0.4, 0.8)                     -> tint               (folded, 1 node)
Multiply                                           -> tint * grey
Constant(1.0), AppendVector                        -> float2(a, 1.0)     (1 node)
Constant(0.0), AppendVector                        -> float3(uv, 0.0)
Add                                                -> Base.EmissiveColor

另请参阅

本页目录