Function 与 helper
HLSL 风格 helper、GraphFunction、输出和自包含模式。
Function 和 GraphFunction 是 DreamShaderLang 的 helper 层。它们让复杂计算留在 HLSL 风格代码里,而不是强行把所有逻辑展开成 Graph 节点。
| helper | 适合 |
|---|---|
Function | 纯 HLSL 风格 Custom 节点逻辑。 |
GraphFunction | 需要在 helper 体内调用 UE.* 图节点,再把结果传入 Custom 节点的逻辑。 |
基本声明
Function ApplyTint(in vec3 color, in vec3 tint, out vec3 result) {
result = color * tint;
}函数头:
Function [SelfContained|Inline] Name(parameter-list) { body }参数:
in Type name
out Type name至少需要一个 out 参数。
单输出 Function 可以作为 Graph 值表达式使用:
Graph = {
vec3 tinted = ApplyTint(baseColor, tint);
}多输出 Function 仍然需要显式传 out 变量。
多输出
Function SplitBrightness(in vec3 color, out vec3 normalized, out float brightness) {
brightness = max(max(color.r, color.g), color.b);
normalized = color / max(brightness, 0.0001);
}调用:
Graph = {
vec3 normalized;
float brightness;
SplitBrightness(Tint, normalized, brightness);
}DreamShader 会为第一个 out 创建 Custom 节点主输出,为后续 out 创建 Additional Output。
GraphFunction
GraphFunction 同样生成 Custom 节点,但函数体里可以直接写 UE.* 调用。DreamShader 会把这些 UE.* 调用转换成材质节点,并把节点输出作为自动生成的 Custom 输入。
GraphFunction BuildPulse(in float scale, out float result) {
float t = UE.Time();
result = sin(t * scale);
}调用方式:
Graph = {
float pulse = BuildPulse(2.0);
}规则:
| 规则 | 说明 |
|---|---|
UE.* | 允许在 GraphFunction 体内使用。 |
| 普通 HLSL | 可以继续使用 sin、saturate、循环等 HLSL 写法。 |
| 单输出 | 可作为值表达式。 |
| 多输出 | 必须显式传 out 变量。 |
| 递归 | 会进行递归调用检测。 |
普通 Function 体内不允许直接调用 UE.*。如果需要图节点输入,改用 GraphFunction。
纹理参数
Namespace(Name="Texture")
{
Function Sample2DRGB(in Texture2D texture, in float2 uv, out float3 color) {
color = Texture2DSample(texture, textureSampler, uv).rgb;
}
}当 Texture2D 作为 Custom 节点输入时,生成器会处理对应 sampler 命名。函数体里常见写法是 textureSampler。
Function 内置函数
VSCode 扩展 1.4.9 起使用统一的 Function builtin metadata,为 HLSL 原生函数、GLSL 风格别名和 Unreal 纹理采样 helper 提供补全、Hover、Signature Help、Inlay Hint、语义高亮和本地诊断白名单。
常用 HLSL 原生函数包括:
abs, acos, all, any, asin, atan, atan2, ceil, clamp, cos, cross,
ddx, ddy, distance, dot, exp, floor, frac, fwidth, length, lerp,
log, max, min, mul, normalize, pow, reflect, refract, round,
rsqrt, saturate, sign, sin, smoothstep, sqrt, step, tan, transposeGLSL 风格别名:
| 别名 | 等价 |
|---|---|
mix | lerp |
fract | frac |
mod | fmod |
Unreal 纹理采样 helper:
Texture2DSample, Texture2DSampleLevel, Texture2DSampleBias, Texture2DSampleGrad,
Texture2DArraySample, Texture2DArraySampleLevel,
TextureCubeSample, TextureCubeSampleLevel,
Texture3DSample, Texture3DSampleLevel示例:
Function SampleVolume(in VolumeTexture texture, in float3 uvw, out float value) {
value = Texture3DSample(texture, textureSampler, uvw).r;
}普通函数与自包含函数
普通 helper:
Function Remap01(in float value, out float result) {
result = saturate(value * 0.5 + 0.5);
}生成行为:
| 行为 | 说明 |
|---|---|
.ush | 生成 helper include 文件。 |
| Custom 节点 | 通过 include 调用生成的函数符号。 |
| 适合 | 当前项目持续使用 DreamShader。 |
自包含 helper:
Function SelfContained Remap01(in float value, out float result) {
result = saturate(value * 0.5 + 0.5);
}生成行为:
| 行为 | 说明 |
|---|---|
| 嵌入代码 | 把需要的 helper 代码写入 Custom 节点。 |
| include | 尽量减少对生成 .ush 的依赖。 |
| 适合 | 需要把生成材质迁移到未安装 DreamShader 的项目。 |
Inline 与 SelfContained 等价:
Function Inline Remap01(in float value, out float result) {
result = saturate(value * 0.5 + 0.5);
}命名空间函数
Namespace(Name="Color")
{
Function ApplyTint(in vec3 color, in vec3 tint, out vec3 result) {
result = color * tint;
}
}调用:
Color::ApplyTint(BaseColor, Tint, ColorOut);命名空间函数在内部会被转换成安全符号,避免 HLSL 里直接使用 ::。
命名空间中也可以声明 GraphFunction:
Namespace(Name="Time")
{
GraphFunction Pulse(in float speed, out float value) {
value = sin(UE.Time() * speed);
}
}设计建议
| 场景 | 建议 |
|---|---|
| 简单节点连接 | 写在 Graph。 |
| 多处复用公式 | 写成 Function。 |
helper 内需要 UE.* 节点 | 写成 GraphFunction。 |
| 循环和复杂流程 | 写成 Function。 |
| 面向团队共享 | 放进 .dsh 或 Package。 |
| 命名可能冲突 | 放进 Namespace。 |
常见错误
| 错误 | 原因 |
|---|---|
Function ... must declare at least one out parameter | 没有声明 out 参数。 |
currently uses positional arguments only | 普通 Function 调用使用了命名参数。 |
out argument must be a plain variable name | out 位置传了表达式,而不是变量名。 |
must be called with explicit out variables | 多输出 Function / GraphFunction 被当作单值表达式使用。 |
UE.* calls are not allowed in Function | 普通 Function 体内调用了图节点入口,应改用 GraphFunction。 |