DreamShaderLang
工具链

命令行

-run=DreamShader —— 每个命令和开关、路径解析、退出码,以及为什么它写真资产而编辑器不写。

-run=DreamShader 是无头入口。它把 DreamShader 源文件编译成持久化资产, 也把已有的材质资产反编译回源文件 —— 没有编辑器 UI,也没有 bridge 在跑。

项目
UDreamShaderCommandlet,在 DreamShaderEditor 模块里
调用-run=DreamShader,等价写法 -run=DreamShaderCommandlet
命令compilegeneratedecompileexport
退出码0 成功,1 失败
日志分类LogDreamShader
Commandlet 标志IsClient = falseIsEditor = trueIsServer = falseLogToConsole = true

commandlet 写的是真 package。 编译时 transient 标志是关的,所以 /Game/….uasset 会被创建并保存到磁盘。 交互式编辑器正好相反 —— 那边每次编译都是纯内存的。这正是在 CI 里把整个项目的源文件落盘的正确方式, 同时也意味着一次 commandlet 运行可能留下遮蔽编辑器内存材质的资产。见内存材质

语法概要

记号含义示例
<x>占位符——替换成实际内容,尖括号本身不写出来。Name = <string>
[ x ]可选——整段可以整体省略。[, Root = <string>]
{ a | b }多选一——从竖线分隔的写法里取其中一个。{ Node( … ) | Comment( … ) }
可重复——前一项可以出现任意多次。<property-declaration> …
UnrealEditor-Cmd.exe <project>.uproject -run=DreamShader <command> [<option>…]

<command> ::= { compile | generate | decompile | export }

-run=DreamShader { compile | generate } { -Source=<path> | -File=<path> | -All } [-Force]
-run=DreamShader { decompile | export } -Asset=<object-path> [{ -Out | -Output }=<path>]

命令

命令名是第一个(不以 - 开头)参数。没有裸参数时,改为查 Command=<name> 参数。 匹配大小写不敏感,首尾空白会被 trim 掉。

写法等价于效果
compile把一个源文件、或全部项目源文件,编译成资产
generatecompile完全相同;另一种写法
decompileUMaterial / UMaterialFunction 图导出成源文件
exportdecompile完全相同;另一种写法

其他任何值都会失败于 Unknown DreamShader command '{Command}'. 加用法横幅,并以 1 退出。

第一个裸 token 会被无条件当成命令名,在做任何校验之前。把一个不带前导短横的选项写在最前面 —— -run=DreamShader Source=X compile —— 会把 Source=X 吃成命令名,得到 Unknown DreamShader command 'Source=X'. 请让命令保持为第一个裸参数。

compile / generate

选项别名类型必需默认含义
-Source=<path>-File=<path>字符串三选一只编译一个源文件
-All标志三选一编译全部项目 DreamShader 源文件
-Force标志绕过 source hash 短路,无条件重新生成

优先级:先查 -Source,再查 -File;两者都没取到值时才看 -All-Source-All 同时给出时, 静默地只编译那一个文件。三者都没有时,用法横幅以 Error 记录,运行以 1 退出。

-Force 只绕过 source hash 短路,它不删除任何东西。

-Source 路径解析

按下列顺序尝试,第一个适用的胜出。

顺序条件结果
1值为空,或者是绝对路径按给定值归一化
2<SourceDirectory>/<value> 存在用这个路径
3<ProjectDir>/<value> 存在用这个路径
4其他按给定值归一化 —— 随后会卡在扩展名守卫或编译上

<SourceDirectory>Source Directory 项目设置,默认 <Project>/DShader。所以相对值先按 DreamShader 源树解析,再按项目目录解析。

-All 的发现与排序

步骤规则
1递归收集 <SourceDirectory> 下的 *.dsm*.dsh*.dsf
2丢掉 <SourceDirectory>/Packages 下的一切
3丢掉 .dsh 头文件 —— 它们不生成资产,会被依赖方内联
4排序:.dsf 函数文件在前(rank 0),.dsm 材质在后(rank 1);同 rank 按大小写不敏感的路径比较

第 4 步是保证,不是巧合:材质引用的函数资产必须在该材质生成之前存在,两级 rank 排序在单次运行内提供了这一点。 第 2 步对住在 package 里的 .dsf 有一处锋利边缘 —— 见 Package

逐文件守卫

编译列表里的每个文件在编译前都会被检查。不是 DreamShader 源文件的路径,或者 .dsh 头文件的路径, 会记 DreamShader compile requires a .dsm or .dsf file: {Path},把整次运行标记为失败, 然后继续处理剩下的文件。所以一个坏文件不会阻止其余文件编译 —— 但进程仍然以 1 退出。

结果消息

每个文件的编译结果原样记录:成功记 Display,失败记 Error。一个文件产出多个资产时,消息用换行连接。

消息结果
Generated {Kind} {AssetPath} from {SourceFile}.生成了 ShaderFunction / ShaderLayer / ShaderLayerBlend 资产;{Kind} 是块关键字
Generated {AssetPath} from {SourceFile}.材质已生成,Graph backend
Generated DreamShader thin-custom material {AssetPath} from {SourceFile}.材质已生成,ThinCustom backend
Skipped {AssetPath} from {SourceFile}; source hash is unchanged.哈希一致 —— 传 -Force 强制重新生成
Generated DreamShader helper include '{Path}' from {SourceFile}.该文件只产出了一个生成的 .ush
DreamShader file '{Path}' contains VirtualFunction declarations only; no assets were generated.成功,没有东西要写
DreamShader file '{Path}' contains GraphFunction declarations only; no assets were generated.成功,没有东西要写
DreamShader file '{Path}' did not contain any material, ShaderFunction, ShaderLayer, or ShaderLayerBlend assets to generate.失败
DreamShader header '{Path}' does not generate assets directly. Recompile dependent .dsm or .dsf files instead.失败 —— 一个 .dsh 进到了生成器
{Path}: .dsf files cannot define top-level Shader blocks.失败

(virtual) 结尾的消息表示 transient 资产;commandlet 从不产出那种。

decompile / export

选项别名类型必需默认含义
-Asset=<object-path>字符串要反编译的资产
-Out=<path>-Output=<path>字符串计算得到目标文件

资产路径归一化

步骤规则
1每个 \ 变成 /
2若路径以 / 开头且不含 .,追加短名:/Game/Path/Asset/Game/Path/Asset.Asset

先加载归一化后的路径。如果失败归一化确实改变了字符串,再原样重试去掉引号的原始输入。

支持的资产类

产出默认目标
UMaterial.dsm<SourceDirectory>/Decompiled/Materials/<package path>.dsm
UMaterialFunction.dsf<SourceDirectory>/Decompiled/Functions/<package path>.dsf
UMaterialFunctionMaterialLayer.dsf<SourceDirectory>/Decompiled/Layers/<package path>.dsf
UMaterialFunctionMaterialLayerBlend.dsf<SourceDirectory>/Decompiled/LayerBlends/<package path>.dsf
其他任何类报错

路径段会被净化:控制字符和 < > : " / \ \| ? * 变成 _;空目录段变成 Folder<N>,空资产段变成 Asset<N>。 输出是 UTF-8 无 BOM。-Out 完全绕过计算出来的目标,必要时创建目录。导出器的完整行为见 反编译导出

参数语法

所有命令共用,并由自动化测试 DreamShader.Commandlet.Args.SplitAndGet 钉住。

规则行为
键归一化trim,然后剥掉所有前导 -,再 trim。-Source--SourceSource 是同一个键
名称匹配大小写不敏感 —— -source-SOURCE-Source 等价
值归一化trim,剥掉一层包裹引号,再 trim
赋值切分第一个 = 处切;因此值里可以含 =
无短横赋值凡是能写 -Key=Value 的地方都接受裸 Key=Value
查找顺序先解析出的参数表,再开关列表,再裸 token 列表;第一个命中胜出
空值-Source= 解析成空串,被当作不存在
缺失键不存在

布尔标志

标志可以裸写,也可以带值。值在匹配前会转小写。

写法结果
-Force
-Force=(空值)
-Force=1 / -Force=true / -Force=yes / -Force=on
-Force=0 / -Force=false / -Force=no / -Force=off
-Force=<其他任何值>

无法识别的布尔值求值为,既不是关,也不是错误。-Force=banana-Force=disable-All=never 全都会启用该标志,而且没有任何诊断。请使用上表里的字面量。

退出码

条件
0所选命令报告成功
0compile -All 解析出的源文件列表 —— 记 Warning,视为成功
1既没有命令 token 也没有 Command=
1未知命令名
1compile-Source / -File / -All 一个都没给
1compile 期间任何逐文件守卫失败或编译失败
1decompile 没有 -Asset,或加载 / 反编译 / 写入失败

哪些东西不会跑

  • commandlet 里 editor bridge 从不启动。 编辑器模块一检测到自己在 commandlet 进程里就从启动流程返回, 所以没有源目录 watcher、没有保存即编译、端口 17864 上没有 WebSocket 服务、没有 diagnostics.json 写入、 没有 bridge.db,也没有菜单注册。
  • 唯一的例外是 cook commandlet,它会装一个 post-engine-init 钩子。只在 cook director 上 —— 即 -run=Cook 且不带 -cookworker 的进程 —— DreamShader 会在正式 cook 之前把每个项目源文件 落成持久资产。那里的生成失败是 Fatal,会中止整个 cook。
  • commandlet 的自动化运行(例如 -ExecCmds="Automation RunTests …")加上 -NoDreamShaderEditorBridge,同样能在那边压掉 bridge —— 见 编辑器工具

诊断

所有消息都进 LogDreamShader。运行期替换写作 {Placeholder}

消息严重度原因
(用法横幅)Error既没有命令 token 也没有 Command=
Unknown DreamShader command '{Command}'. + 用法横幅Error命令不是 compile / generate / decompile / export
(用法横幅)Errorcompile-Source / -File-All 都没给
DreamShader commandlet found no source files to compile.Warning解析出的源文件列表为空;运行仍以 0 退出
DreamShader compile requires a .dsm or .dsf file: {Path}Error该文件不是 DreamShader 源文件,或者是 .dsh 头文件
(编译结果消息)Display / Error逐文件结果 —— 见结果消息
(用法横幅)Errordecompile 没有 -Asset
DreamShader could not load asset '{AssetPath}'.Error归一化路径和原始路径都加载失败
DreamShader failed to decompile '{LoadPath}': {Error}Error反编译器报告失败
DreamShader decompile supports Material and MaterialFunction assets only: {AssetPath}Error不支持的资产类
Decompile did not produce source text.Error反编译失败但没有错误文本
DreamShader failed to resolve an output file path.Error目标路径解析为空
DreamShader failed to create output directory '{Directory}'.Error目标目录创建失败
DreamShader failed to write decompiled source '{Path}'.Error文件写入失败
DreamShader decompiled '{LoadPath}' to '{OutputPath}'.Display成功

用法横幅,原文:

Usage:
  -run=DreamShader compile -Source="C:/Project/DShader/File.dsm" [-Force]
  -run=DreamShader compile -All [-Force]
  -run=DreamShader decompile -Asset="/Game/Path/Asset.Asset" [-Out="C:/Project/DShader/Decompiled/File.dsm"]
Supported asset types: Material -> .dsm, MaterialFunction -> .dsf.

示例

编译单个源文件,绕过哈希短路:

& "C:\Program Files\Epic Games\UE_5.5\Engine\Binaries\Win64\UnrealEditor-Cmd.exe" `
  "C:\Projects\MyGame\MyGame.uproject" `
  -run=DreamShader compile -Source="C:/Projects/MyGame/DShader/Materials/M_Sample.dsm" -Force `
  -unattended -nopause -nosplash -stdout -log

作为 CI 关卡,编译全部项目源文件 —— .dsf 在前,.dsm 在后:

& "C:\Program Files\Epic Games\UE_5.5\Engine\Binaries\Win64\UnrealEditor-Cmd.exe" `
  "C:\Projects\MyGame\MyGame.uproject" `
  -run=DreamShader compile -All -Force `
  -unattended -nopause -nosplash -stdout -log

把已有材质反编译到指定路径:

& "C:\Program Files\Epic Games\UE_5.5\Engine\Binaries\Win64\UnrealEditor-Cmd.exe" `
  "C:\Projects\MyGame\MyGame.uproject" `
  -run=DreamShader decompile -Asset="/Game/Materials/M_Existing" `
  -Out="C:/Projects/MyGame/DShader/Decompiled/Materials/M_Existing.dsm" `
  -unattended -nopause -nosplash -stdout -log

相对的 -Source 先按 DShader/ 解析:

-run=DreamShader compile -Source="Materials/M_Sample.dsm"

一次成功的两文件 -All 运行的控制台输出:

LogDreamShader: Display: Generated ShaderFunction /Game/Functions/MF_Noise from C:/Projects/MyGame/DShader/Functions/MF_Noise.dsf.
LogDreamShader: Display: Generated DreamShader thin-custom material /Game/Materials/M_Sample from C:/Projects/MyGame/DShader/Materials/M_Sample.dsm.

继续阅读

本页目录