DreamShaderLang
语言核心

Graph 语言

DreamShaderLang 中用于生成 Unreal 材质节点的图 DSL。

Graph = { ... } 是 DreamShaderLang 的材质图层。它不是完整通用语言,而是一门用于创建和连接 Unreal MaterialExpression 节点的 DSL。

语句

Graph 语句以分号结束:

Graph = {
    float a = 1.0;
    float b = 2.0;
    float c = a + b;
}

支持的语句:

语句示例
声明float value;
声明并初始化vec3 color = vec3(1.0, 0.0, 0.0);
赋值Color = Tint;
表达式语句ApplyTint(A, B, Result);
if / elseif (Mask > 0.5) { ... } else { ... }

声明

float a;
float2 uv;
float3 color;
float4 sampleValue;

只声明不初始化时,会创建对应类型的默认值,标量和向量默认是 0

同一条语句可以写逗号分隔声明:

float a = 1.0, b = 2.0, c;

表达式

算术

支持:

a + b
a - b
a * b
a / b
-a
+a

这些表达式会生成 AddSubtractMultiplyDivide 等材质节点。纹理对象不能参与算术。

构造器

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

Swizzle

float r = color.r;
float2 rg = color.rg;
float3 xyz = normal.xyz;

支持通道:

通道族通道
坐标风格x / y / z / w
颜色风格r / g / b / a

函数调用

Graph 中有三类调用:

float2 uv = UE.TexCoord(Index=0);

vec3 result;
ApplyTint(color, tint, result);

vec3 tinted = F_Tint(InColor=color, InTint=tint);
调用返回方式
UE.*返回一个图值,可赋值。
Function必须作为表达式语句调用,并传显式 out 变量。
ShaderFunction返回材质函数输出,可作为表达式使用。

Function 调用

定义:

Function ApplyTint(in vec3 color, in vec3 tint, out vec3 result) {
    result = color * tint;
}

调用:

Graph = {
    vec3 src = vec3(1.0, 0.4, 0.2);
    vec3 tint = vec3(0.5, 1.0, 1.0);
    vec3 result;

    ApplyTint(src, tint, result);
}

限制:

规则说明
位置参数当前 Function 调用只支持位置参数。
显式 out所有 out 参数必须传普通变量名。
不可作为值result = ApplyTint(src, tint); 不支持。

ShaderFunction 调用

如果项目中声明并生成了:

ShaderFunction(Name="Functions/F_Tint")
{
    Inputs = {
        vec3 InColor;
        vec3 InTint;
    }

    Outputs = {
        vec3 OutColor;
    }

    Graph = {
        OutColor = InColor * InTint;
    }
}

可以在其他 Graph 中调用:

Graph = {
    vec3 tinted = F_Tint(InColor=BaseColor, InTint=Tint);
    Color = tinted;
}

如果 ShaderFunction 有多个输出,必须指定:

float value = F_MultiOutput(Input=Mask, Output="Height");
float other = F_MultiOutput(Input=Mask, OutputIndex=1);

if / else

Graph 支持基础条件分支:

Graph = {
    float mask = UE.Expression(Class="ComponentMask", OutputType="float1", Input=UV, R=true);

    if (mask > 0.5) {
        Color = vec3(1.0, 0.2, 0.2);
    } else {
        Color = vec3(0.0, 0.0, 0.0);
    }
}

条件支持:

写法语义
if (Mask)等价于 Mask > 0
> / <大于 / 小于。
>= / <=大于等于 / 小于等于。
== / !=等于 / 不等于。

生成器会创建 Unreal Material If 节点来合并分支结果。条件两侧必须是标量。分支不能选择 Texture2DTextureCubeTexture2DArray 值。

当前不支持

特性建议替代
for / while放进 Function 的 HLSL helper。
任意 HLSL 语句放进 Function
返回值风格 Function使用显式 out 参数。
纹理分支选择在 helper 中处理采样结果,或分支选择数值结果。

On this page