DreamShaderLang
语言核心

类型与值

44 个类型 token、分上下文的有效性矩阵、GLSL 别名、字面量,以及已经不存在的那些 token。

类型 token 是语言里每一种声明形式的第一个元素。这个集合是封闭的 —— 一共 44 个 token,没有用户自定义 类型 —— 而且在所有上下文中都按大小写不敏感匹配

// Properties section
[const] <type> <name> [ = <default> ] [ [ <metadata> ] ] ;

// 材质函数的 Inputs / Outputs / Results
[opt] <type> <name> [ = <default> ] [ [ <metadata> ] ] ;

// Shader Outputs 变量声明
<type> <name> [ = <expression> ] ;

// Function / GraphFunction 签名
Function [ <type> ] <name> ( [ { in | out } ] <type> <name> , … ) { … }

// Graph 声明
<type> <name> [ = { <expression> | { <brace-initializer> } } ] ;
记号含义示例
<x>占位符——替换成实际内容,尖括号本身不写出来。Name = <string>
[ x ]可选——整段可以整体省略。[, Root = <string>]
{ a | b }多选一——从竖线分隔的写法里取其中一个。{ Node( … ) | Comment( … ) }
可重复——前一项可以出现任意多次。<property-declaration> …

Token 家族

家族Token数量
标量(1 分量)float float1 half half1 int uint bool7
向量(2 / 3 / 4 分量)float2..4 half2..4 vec2..4 int2..4 uint2..4 bool2..4 ivec2..4 uvec2..4 bvec2..427
纹理Texture2D TextureCube Texture2DArray Texture3D VolumeTexture5
不透明 / 其他SamplerState MaterialAttributes Substrate StaticBool StaticBoolParameter5

没有 vec1ivec1uvec1bvec1,也没有 half 的 GLSL 向量拼法。单分量的 GLSL 风格写法根本 不存在 —— 用 floatfloat1

六个上下文

各个声明位置并不共用同一个类型集合。下面矩阵的每一列对应一个位置。

位置
PropShader / ShaderFunction / ShaderLayer / ShaderLayerBlendProperties
I/O材质函数或 VirtualFunctionInputs / Outputs / Results(以及 VirtualFunction 里作为 Inputs 别名的 Properties
Fn inFunction / GraphFunctionin 参数
Fn outFunction / GraphFunctionout 参数,或声明的返回类型
Out declShaderOutputs section 里的变量声明
GraphGraph 块里的声明语句

Prop解析阶段校验;其他每一列都在生成阶段、也就是这条声明第一次被使用时才校验。一个参数 类型不被接受的 Function 能干净地解析通过,只有当有人调用它时才失败。

有效性矩阵

接受 · 拒绝。分量是图构建器看到的值宽度;0 表示不携带通道的不透明值。

Token分量PropI/OFn inFn outOut declGraph
float float1 half half1 int uint bool1
float2 half2 vec2 int2 uint2 bool2 ivec2 uvec2 bvec22
float3 half3 vec3 int3 uint3 bool3 ivec3 uvec3 bvec33
float4 half4 vec4 int4 uint4 bool4 ivec4 uvec4 bvec44
Texture2D0✔ ⁽¹⁾✔ ⁽²⁾
TextureCube0✔ ⁽¹⁾✔ ⁽²⁾
Texture2DArray0✔ ⁽¹⁾✔ ⁽²⁾
Texture3D0✔ ⁽¹⁾✔ ⁽²⁾
VolumeTexture0✔ ⁽¹⁾✔ ⁽²⁾
SamplerState0✔ ⁽³⁾✔ ⁽³⁾⁽⁴⁾✔ ⁽²⁾⁽³⁾
MaterialAttributes0✔ ⁽⁵⁾
Substrate0✔ ⁽⁶⁾✘ ⁽⁷⁾✘ ⁽⁷⁾✔ ⁽⁶⁾✔ ⁽²⁾⁽⁶⁾
StaticBool1
StaticBoolParameter1✔ ⁽⁸⁾
  1. Function 的纹理类型 in 参数还会在生成的 HLSL 签名里紧随其后多出一个 SamplerState <Name>Sampler 参数,每个调用点也会在实参后插入 <argument>Sampler。见 函数
  2. Graph 块里的纹理、SamplerStateSubstrate 声明必须带初始化式 —— 它们没有默认值。 错误:Graph variable type '{Type}' requires an explicit initializer.
  3. 在每一个接受它的上下文里,SamplerState 都是 Texture2D 的别名。它解析成一个 Texture2D 纹理对象,而不是独立的采样器值。
  4. SamplerState 不在触发注 1 那个伴随采样器展开的集合里,所以 SamplerStatein 参数在生成的 HLSL 里就是 SamplerState <Name>,调用点收到的是一个纹理对象。
  5. MaterialAttributes 能作为 Function 输入类型解析,但这个 token 会原样写进生成的 HLSL 签名 —— 见 生成的 HLSL 拼写
  6. Substrate 需要 since UE 5.4。更老的引擎上这个 token 根本解析不了,会发出对应位置的 "requires Unreal Engine 5.4 or newer" 诊断。
  7. Substrate 能作为 Function / GraphFunction 的参数或结果类型解析,随后被专门的消息拒绝。
  8. Properties 里,StaticBoolParameter参数节点 token,不是类型 token:它生成一个 UMaterialExpressionStaticBoolParameter,默认值只接受 true / false。见 Properties 类型

GLSL 别名

vec / ivec / uvec / bvec 拼法在其 float / int / uint / bool 对应写法被接受的每个位置都是 一等 token。它们在 PropertiesInputsOutputsGraph 声明和 Graph 构造器里不会被改写。

GLSL 拼法等价于
vec2 vec3 vec4float2 float3 float4
ivec2 ivec3 ivec4int2 int3 int4
uvec2 uvec3 uvec4uint2 uint3 uint4
bvec2 bvec3 bvec4bool2 bool3 bool4

因为 intuintboolhalf 最终都塌缩成同样的浮点分量数,在 int3ivec3bool3float3 之间选哪个纯粹是文档意义。唯一可观测的差别是 Graph 块里整数构造器调用设置的整数标记, 它存在的唯一目的是拒绝整数除法。见 运算符与转换

Function 函数体内的改写

Function / GraphFunction签名会把每个类型 token 过一遍规范化器,函数体则会把每个标识符过 同一张映射表的超集。两者都按小写化的整个标识符匹配。

被改写的标识符变成签名类型中函数体文本中
vec2 vec3 vec4float2 float3 float4
ivec2 ivec3 ivec4int2 int3 int4
uvec2 uvec3 uvec4uint2 uint3 uint4
bvec2 bvec3 bvec4bool2 bool3 bool4
mat2float2x2
mat3float3x3
mat4float4x4
mixlerp
fractfrac
modfmod

签名 15 个别名,函数体 18 个。改写感知注释和字符串,而且作用于 FunctionGraphFunction 的 函数体 —— Graph 块永远不会被规范化。在 Graph 块里,fractmod 是真正的数学内置 since 1.5.0mixlerp 的真别名;见 数学内置

函数体改写按整个标识符匹配且忽略大小写。FunctionGraphFunction 函数体里名为 MixModFractVec3Mat4 的 helper、局部变量或结构体成员,会被静默改名成 lerpfmodfracfloat3float4x4。没有任何诊断;失败表现为 HLSL 编译错误,或者悄悄算错。请改名。

矩阵

没有矩阵类型。 mat2 / mat3 / mat4float2x2 / float3x3 / float4x4 被上面矩阵的每一列 拒绝。

不过 mat2 / mat3 / mat4Function 签名里词法上是被接受的,因为规范化器在任何校验之前就把 它们改写掉了。于是声明能解析通过,调用时才失败:

Function float3 Rotate(in mat3 basis, in vec3 v) { return mul(basis, v); }
// 能解析;调用时失败于:
//   DreamShader Function 'Rotate' input 'basis' uses unsupported type 'float3x3'.

矩阵形状的运算只能通过 transform 内置完成 —— 见 UE.* 节点

字面量

标量

float a = 1.0;
float b = -0.5;
float c = 1e-3;

Graph 块里,数字是真正的 token,可带指数和一个可选类型后缀(f F h H u U l L),后缀不进入值: 0.55f 就是 0.55。在声明默认值里根本没有数字 token —— 原始文本被延后且宽容地转换,所以 float Strength = 1abc; 会静默变成 1.0。见 词法与大小写

向量构造

vec2   uv    = vec2(0.5, 0.5);
vec3   color = vec3(1.0, 0.2, 0.1);
float4 rgba  = float4(color, 1.0);

构造器的分量数取自名字的最后一个字符…2 → 2,…3 → 3,…4 → 4,其他 → 1。只要各部分加起来 等于目标宽度,构造器接受标量和向量的任意组合。

Brace initializer

vec3   color = {1.0, 0.2, 0.1};
float4 rgba  = {color, 1.0};

适合把已有的标量或向量拼成目标类型,而不必重复写类型名。

布尔与字符串

truefalse 在声明默认值里被接受,需要标量的地方会转成 1.0 / 0.0。字符串字面量用于 settings 值、元数据、类名和 UE.* 的命名参数;它们不是表达式能参与运算的值。

Settings = { Domain = "UI"; }

float pulse = UE.Expression(Class="Sine", OutputType="float1", Input=UE.Time());

资产引用

纹理和资产类声明写 Path( … ) 引用,而不是字面量:

Properties = {
    Texture2D   MainTex     = Path(Game, "Textures/T_Main");
    Texture2D   PluginTex   = Path(Plugins.MoonToon, "Textures/T_Plugin");
    Texture2D   DefaultTex  = Path("/Engine/EngineResources/DefaultTexture");
    TextureCube SkyTex      = Path(Engine, "EngineResources/DefaultTextureCube");
}

每一种被接受的写法、两套解析器及其全部诊断见 Path 资产引用

Token 内部的空白

Fn inFn outOut declGraph 使用的标量 / 向量解析器会先把 token 小写化,再去掉每一个 空格才比较,MaterialAttributes / Substrate 判定也一样。纹理、SamplerStateStaticBool 的 token 是逐字比较的(只忽略大小写),所以 Texture 2D 不能解析。

写法解析为
float 3float3
Material AttributesMaterialAttributes
Sub strateSubstrate

Properties 的分派器不做这件事,所以那里的 float 3 X; 会切成类型 float 和名字 3 X,失败方式 也不一样。

生成的 HLSL 拼写

Function 被降级成生成的 .ush helper 时,每个声明 token 都会写进 HLSL 签名,只应用一条改写:

声明的 token产出的 HLSL
VolumeTextureTexture3D
其他一切原样输出

因为 token 是原样输出的,那些能在 DreamShader 侧解析、却没有 HLSL 拼法的 token —— MaterialAttributesStaticBoolStaticBoolParameter —— 会产出 Unreal 无法编译的 helper。 DreamShader 侧的校验会通过,失败表现为一条指出未知类型名的 shader 编译错误。MaterialAttributes 和 静态布尔的传递请改用 ShaderFunctionGraphFunction

已移除的 token

Token状态替代
Scalar已移除float
Color已移除float4 / vec4
Vector已移除float2float4 / vec2vec4

它们没有在任何地方被特殊处理,会落进所处上下文的通用"不支持的类型"诊断 —— 在 Properties 里是 Unsupported property type 'Scalar'.,在 Graph 块里是 Unsupported Graph variable type 'Color' for '{Name}'.

示例

每个家族各取一个 token,各自放在接受它的上下文里:

ShaderFunction(Name="Functions/F_Types")
{
    Properties = {
        float     Strength = 1.0;              // 标量 token
        vec3      Tint     = vec3(1, 1, 1);    // GLSL 向量拼法
        Texture2D Noise    = Path(Game, "Textures/T_Noise");
    }

    Inputs = {
        vec2                   UV;             // 数值
        opt StaticBool         UseTint;        // 仅 Inputs 可用的 token
        opt MaterialAttributes InAttrs;        // 仅 Inputs 可用的 token
    }

    Outputs = {
        vec3 OutColor;
    }

    Graph = {
        Texture2D Src = Noise;                 // 纹理声明必须带初始化式
        vec4   Sampled = SampleTexture2D(Src, UV);
        float3 Base    = Sampled.rgb * Strength;
        OutColor       = Base * Tint;
    }
}

诊断

消息触发原因处理
Unsupported property type '{Type}'.Properties 不接受这个 token —— MaterialAttributes、Substrate、SamplerState、StaticBool 都在其中。详解
Unsupported Graph variable type '{Type}' for '{Name}'.Graph 声明不接受这个 token。详解
Graph variable type '{Type}' requires an explicit initializer.Graph 块里的纹理、SamplerState 或 Substrate 声明没有写 =。
Unsupported output type '{Type}' for '{Name}'.Shader 的 Outputs 声明不接受这个 token。
{Kind} '{Function}' input '{Name}' uses unsupported type '{Type}'.Inputs section 不接受这个 token —— 常见原因是制表符混进了类型 token。详解
{Kind} '{Function}' output '{Name}' uses unsupported type '{Type}'.Outputs / Results section 不接受这个 token。
DreamShader Function '{Name}' input '{Input}' uses unsupported type '{Type}'.Function 的 in 参数不接受这个 token —— 矩阵会走到这条。详解
DreamShader Function '{Name}' has unsupported result type '{Type}'.结果类型不在标量 / 向量 / MaterialAttributes 集合内。
Graph variable '{Name}' uses Substrate, which requires Unreal Engine 5.4 or newer.在 UE 5.3 上写了 Substrate 声明。详解
DreamShader Function '{Name}' input '{Input}' uses Substrate, which is not supported by HLSL Custom node functions. Use GraphFunction or ShaderFunction instead.UE 5.4+ 上给 Function 写了 Substrate 参数。
Expected a MaterialAttributes value.在声明为 MaterialAttributes 的位置赋了一个数值。
Expected a texture object value with a matching texture type.赋了一个维度不匹配的纹理。
Texture objects cannot be assigned to numeric outputs.纹理对象被赋给了数值目标。

继续阅读

本页目录