DreamShaderLang
生成与产物

版本控制

2.0 起哪些生成资产会落盘、给它们做版本管理的两套可行做法,以及 dsc list-generated —— ignore 规则和 P4 typemap 就是照它写的。

提交什么、忽略什么,以及怎么让一个团队只有一种答案。

项目值
永远提交每一个 .dss、.dsi、.dsh、.dsm、.dsf —— 源码才是材质本身
永远不提交Intermediate/DreamShader/、Saved/DreamShader/
由你决定生成出来的 .uasset —— 这一页讲的就是这个决定
工具dsc list-generated —— 不构建任何东西,列出源码会生成的全部资产
起始版本since 2.0.0

为什么这里有一个选择

整个 1.x 时期,交互式编辑器把生成资产放在内存里,所以大多数工程在 cook 之外从没见过生成的 .uasset。 从 2.0 起,只有一种产物还是这样。

产物是否落盘
Graph 后端的材质总是 —— 每次成功生成都会保存
材质函数、层、层混合总是
材质实例(.dsi)总是
ThinCustom 后端的材质只有物化之后才有;默认是纯内存的,此时根本没有文件

UMaterial 和 UMaterialFunction 是引擎自带的类,没有办法让自己不被资产枚举到,所以一生成就保存 —— 就落在大家手工做的资产旁边,版本控制工具会提示你把它们加进去。请以工程为单位做一次决定。 「一半生成资产提交了、一半被忽略」是唯一行不通的安排。

生成资产的出身记在 package metadata 里(DreamShader.SourceFile、DreamShader.SourceHash、 DreamShader.OutputDigest),而不是 asset registry tag —— 插件没法给引擎自带的类加 tag。 在编辑器里,Material Content Browser 按它筛选;在编辑器外,去问源码,list-generated 做的正是这件事。

列出生成资产

./dsc.ps1 list-generated -All                                             # package 名
./dsc.ps1 list-generated -All -ListAs Files     -Out generated-files.txt  # 相对工程目录的路径
./dsc.ps1 list-generated -All -ListAs GitIgnore -Out generated.gitignore  # 一段带锚定的 .gitignore
./dsc.ps1 list-generated -All -ListAs Json      -Out generated.json       # 全部字段

清单是从源码算出来的 —— 前端、绑定器、资产去向规则 —— 不构建、不加载、不保存任何东西。 纯内存的材质默认不列(它没有文件可忽略),除非加 -IncludeEphemeral。编不过的源文件仍然会贡献失败之前已经确定的产物, 并且整次运行以 RESULT=FAILED 结束,所以清单不会悄悄变短。脚本请始终传 -Out 再读文件;日志是给人看的。

做法 A —— 源码入库,资产不入库

生成资产就是构建产物。没人提交它们;每台机器自己构建。

  • 忽略它们。 用 -ListAs GitIgnore 刷新 .gitignore 里一段带标记的块;或者更简单 —— 当生成资产都放在自己的文件夹里时 —— 每个文件夹一行。.p4ignore 用同样的路径。
  • 构建它们。 全新检出的工作区里没有生成资产,任何引用它们的东西都要等它们存在之后才能解析。
时机由什么来构建
sync / checkout 之后./dsc.ps1 compile -All —— 做成 post-checkout hook 或同步步骤
打开编辑器启动时与保存时都会编译源码
cookcook director 会先编译并保存全部工程源码
CIcheck -All 给源码把关;在任何要加载内容的步骤之前跑 compile -All

代价:手改过的生成资产只存在于一台机器上 —— 而这正是这套做法的本意。用 Adopt Into Source 在它丢失之前把改动搬进源码。

做法 B —— 把生成资产也提交

生成资产是「碰巧被纳入版本管理的派生二进制」,就像工程给 lightmap 做版本管理那样。

  • Git —— 和其他 .uasset 一样对待。
  • Perforce —— 给它们 binary+w 类型,这样编译不用 checkout 就能覆盖;否则每次保存源码都会因为文件只读而失败。 不要加 +l:给一个「工具会替所有人重写」的文件上排他锁,等于排队。
  • 保持诚实。 让 CI 证明提交进来的资产与源码一致:
./dsc.ps1 compile -All              # 没变的源码按 build key 跳过:不重写、没有 diff
git status --porcelain -- Content   # 必须什么都不输出

build key 还覆盖插件版本、引擎版本,以及源码读过的宏,所以升级 DreamShader 或引擎会让一切重新生成。 请把它单独放进一个提交。生成资产的合并冲突靠重新编译解决,永远不要二选一。

选哪个

A —— 不入库B —— 入库
仓库体积只有源码每次重新生成都会长大
全新检出后能否直接打开要先跑一次编译立刻可以
没有插件工具链的人构建不了 —— 不可行没问题
过期资产不可能出现可能;上面的 CI 检查会抓到
升级插件或引擎没有东西要提交一次很大的重新生成提交
手改过的生成资产在被 adopt 之前只在本地被纳入版本管理,并被标记为已分歧

做法 A 适合人人都开着带插件的编辑器的团队;做法 B 适合有人只消费内容的团队。不管选哪个,ThinCustom 后端都让问题变小: 纯内存的材质没有文件,需要做决定的只剩它的函数、它的实例,以及被物化过的那些。

本页目录