7.3 KiB
7.3 KiB
Shader 与 Material 下一阶段:ShaderLab 正式化与 Builtin Shader 资产布局计划
日期:2026-04-07
1. 阶段结论
上一阶段已经完成了最关键的主线收口:
.shader现在只表示 authoring shader,不再兼容 JSON manifest。- 旧的 manifest 主路径已经从运行时主流程移除。
- shader / material / editor 相关测试已经回归通过。
- 当前 shader 主线终于从“过渡态”进入了“可以继续正规化”的状态。
这意味着接下来不应该再围绕“兼容旧双路径”打补丁,而应该开始正式推进:
ShaderLab authoringMaterial contractbuiltin shader asset layoutruntime pass contract
一起向 Unity 风格继续收口。
2. 当前真实状态
当前已经成立的事实:
.shader主语义已经统一。- authoring parser 已经能承载基础的
Shader / Properties / SubShader / Pass / Tags / HLSLPROGRAM / pragma / 基础状态。 - runtime 已经有
Shader -> Pass -> Variant数据模型。 - builtin shader 已经基本都迁入 authoring 主路径。
但当前还没有完全完成的部分也很明确:
- 语法还只是 Unity ShaderLab 的一个子集。
- builtin shader 资产目录结构还带有明显的过渡痕迹。
- material 与 shader 的契约虽然比之前干净,但还没完全达到 Unity 式心智模型。
- renderer 对 pass contract 的消费还可以继续正规化。
3. Builtin Shader 资产目录结论
这里先把结论写死:
engine/assets/builtin/shaders下的主入口 shader 文件,不需要再一 shader 一子文件夹。- 既然当前主入口已经都是单个
.shader文件,那么更合理的结构应该是:
engine/assets/builtin/shaders/
forward-lit.shader
unlit.shader
depth-only.shader
shadow-caster.shader
object-id.shader
object-id-outline.shader
skybox.shader
color-scale-post-process.shader
final-color.shader
- 需要保留子目录的,不是 builtin shader 入口文件本身,而是公用 include / shader library。
- 因此公共代码应该独立成类似:
engine/assets/shaderlib/
Core.hlsl
Common.hlsl
Lighting.hlsl
SpaceTransforms.hlsl
Shadow.hlsl
MaterialInput.hlsl
也就是说:
builtin/shaders/:放“逻辑 shader 资产入口”shaderlib/:放“共享 include 库”
而不是继续维持“每个 shader 一个文件夹,文件名还重复一遍”的结构。
这更符合现在的真实资产形态,也更利于后续继续扩展 builtin shader 数量。
4. 下一阶段目标
下一阶段的目标不是做更多渲染效果,而是把 shader/material 底座继续正规化,达到可以稳定承接后续 SRP 的程度。
这一阶段的目标分成四件事:
- 收口 builtin shader 资产布局。
- 扩展 ShaderLab authoring 子集,继续向 Unity 靠拢。
- 继续压缩 material 中残留的临时职责。
- 让 renderer 对 pass / keyword / variant 的消费边界更正式。
5. 分阶段执行
Phase A:Builtin Shader 资产布局拍平
目标:
- 把
engine/assets/builtin/shaders/*/* .shader收口成单层.shader文件布局。 - 同步清理
BuiltinResources中的路径映射和命名。
工作项:
- 拍平 builtin shader 文件路径。
- 更新
BuiltinResources.cpp/.h中的 builtin shader relative path 表。 - 回归所有 builtin shader loader 测试。
- 回归 editor / renderer 中依赖 builtin shader path 的测试。
完成标准:
engine/assets/builtin/shaders/单层化。- 所有 builtin shader 路径 helper 仍稳定工作。
Phase B:扩展 ShaderLab authoring 子集
目标:
- 把当前 authoring 语法从“基础可用”推进到“真正像 Unity ShaderLab 的工程可用子集”。
优先支持:
BlendOpOffsetStencilUsePass- 更完整的
Tags - 更稳的
SubShader级状态继承与覆盖规则
工作项:
- 扩 parser / IR。
- 为新增语法补单测。
- 为 builtin shader 和后续材质/渲染用例补回归用例。
完成标准:
- 这些语法不再停留在计划里,而是进入实际 parser / runtime contract。
Phase C:Material 契约继续收口
目标:
- 让 material 更接近 Unity 的角色定位:只管理 shader、properties、textures、keywords、必要的 render state override。
工作项:
- 继续压缩 legacy
shaderPass的主路径影响范围。 - 梳理 property 到 constant buffer 的稳定映射。
- 梳理 keyword 集与 variant lookup 的契约边界。
- 审查 material loader 中是否还存在对旧 shader 体系的隐式兼容假设。
完成标准:
- material 不再承担本应属于 renderer 的 pass 选择职责。
Phase D:Renderer 消费链继续正规化
目标:
- 让 renderer 更正式地围绕
LightMode / pass contract / keywords / backend选用 pass 与 variant。
工作项:
- 审查 builtin pipeline 中的 pass 选择逻辑。
- 审查 keyword 参与 variant 选择与 pipeline cache 的路径。
- 清理仍然依赖旧约定字符串兜底的代码。
完成标准:
- shader/material/runtime 三者的职责边界更加稳定,不再互相越界兜底。
6. 测试要求
这一阶段必须保持“每做一层就立刻回归”,不能再先堆实现后补测试。
至少要持续回归:
shader_testsmaterial_testseditor_tests中 shader path / viewport render flow / overlay 相关用例XCEditor编译- 受影响的 rendering 单测与关键集成测试
如果 builtin shader 资产布局拍平,必须额外回归:
- builtin shader loader
- object-id / outline / grid / final-color / skybox 相关路径与运行时消费
7. 风险与控制
风险 1:目录结构重构把路径引用打坏
控制策略:
- 先只拍平 builtin shader 主入口文件。
shaderlib不混入builtin/shaders同层迁移,避免一次改太多。- 先跑 loader / editor path / renderer path 回归,再考虑下一层。
风险 2:语法扩展过快,把当前稳定 authoring 再次打回过渡态
控制策略:
- 只扩“明确服务于 Unity 风格主线”的语法。
- 不引入新的双路径兼容层。
- 任何新语法都必须先建测试,再接运行时。
风险 3:material 与 renderer 职责再次混淆
控制策略:
- 每做一项都用“这件事在 Unity 里是谁负责”来校验职责归属。
8. 收口判定
满足下面条件时,这一阶段可以认为完成:
- builtin shader 资产目录已经拍平到单层主入口结构。
BuiltinResources与相关路径 helper 已同步完成。- ShaderLab authoring 子集新增一轮关键语法支持并有测试覆盖。
- material 对旧路径的临时兼容进一步缩小。
- renderer 的 pass / variant 消费逻辑进一步正规化。
- shader / material / editor / XCEditor 回归全部稳定。
9. 下一步执行顺序
建议的实际执行顺序如下:
- 先做 builtin shader 资产布局拍平。
- 立刻回归 shader/material/editor 路径相关测试。
- 再开始扩 ShaderLab 子集。
- 然后收 material 与 renderer 的契约边界。
也就是说,下一步最应该先做的不是再加语法,而是先把 builtin shader 资产布局收干净。