Skip to content

RFC: 自定义/注入式 uniform 与引擎内置 uniform 的命名冲突应收敛到 Shader 层处理 #3020

Description

@cptbtptpbcptdtptp

背景

#3004 给粒子加了 CustomData:用户起的 stream name 会被拼成 renderer_<name><suffix> 的 uniform,写进 ParticleRenderer 的 shaderData,供自定义粒子 shader 读取。

为防撞名,最初用了前缀黑名单 _reservedPrefixPattern = /^(?:VOL|FOL|SOL|COL|ROL|TSA|LVL)/#3019 把它删掉了——因为过宽:COLOR/VOLUME 只是以 COL/VOL 开头,生成的 renderer_COLOR… 与内置 renderer_COL… 并不相等,却被误拒。

删黑名单是对的,但它把“误拒”换成了“完全不拦”:真正精确撞名(如 stream 命名 "COL"renderer_COLMaxGradientColor,与 ColorOverLifetime 内置 uniform 逐字符相同)现在没有任何运行时防护,只靠文档约定。

问题本质

这不是粒子独有问题,而是“用户/子系统提供的 uniform 名”与“引擎内置 uniform 名”共享同一命名空间的通用冲突:

  • 引擎内置 uniform 用 renderer_/material_/scene_/camera_ 前缀,但这只是约定,分散在 ~71 处各模块的 ShaderProperty.getByName(...),无集中登记。
  • ShaderData._setPropertyValuepackages/core/src/shader/ShaderData.ts:656-668)已能拦两类冲突:跨 group 同名(throw ... has been used as X group)和类型不一致(throw)。
  • 唯一拦不住的是同 group + 同类型 + 同名 → 后写静默覆盖。粒子 CustomData 恰落在这一类:它把用户名注入 Renderer group,与内置粒子模块写在同一个 shaderData,同名直接互相覆盖、无报错。

即:普通自定义材质撞内置名(跨 group)会响亮报错;真正危险且无防护的是“把用户字符串动态拼进 uniform 名”这个模式——目前只有粒子 CustomData 这一处,但这是会扩散的模式。

为什么应在 Shader 层解决

每个自定义 shader 的 uniform 最终都要经过 shader 编辑/编译层(ShaderLab,packages/shader-lab),这是唯一能统一收口的地方:

  1. 由 Shader 层持有“引擎保留 uniform 名 / 保留命名空间”的唯一事实源,而非每个子系统各自维护黑名单(黑名单是第二事实源,会随引擎加 uniform 漂移——正是 fix(particle): stop CustomDataModule from false-rejecting stream names by prefix #3019 删它的理由)。
  2. 编写/编译期校验或重写用户 uniform 名,而非运行期:运行期在 ShaderData 里没法对“同 group 同名覆盖”一刀切报警,因为引擎每帧都在合法地覆盖自己的 uniform。
  3. RFC: Shader Static Analyzer #3017(RFC: Shader Static Analyzer)天然契合——“用户 uniform 撞保留名”正是一条可由静态分析器检查的规则。

可选方向(待讨论)

A. 保留命名空间隔离(首选) — 约定引擎内置独占裸 renderer_/material_/scene_/camera_;任何用户/子系统注入的 uniform 名一律落到引擎保证永不使用的保留子命名空间(如 renderer_custom_<name>)。撞名结构上不可能发生,无需运行时检查、无黑名单、无漂移。粒子 CustomData 改为生成 renderer_custom_<name>

B. Shader 层维护保留名集合 + 编译期校验 — ShaderLab 持有引擎保留 uniform 名的权威集合(最好由引擎声明自动生成,避免手维护漂移),自定义 shader / CustomData 声明撞名时编译期 warn/error。

相关

Metadata

Metadata

Assignees

Labels

RFCenhancementNew feature or requestshaderShader related functions

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions