Refactor Cesium material export contract

This commit is contained in:
2026-08-03 11:52:38 +08:00
parent 50dc5f4e5a
commit 0635c09458
16 changed files with 583 additions and 95 deletions

View File

@@ -78,8 +78,9 @@ catalog.MATERIALS 声明「是什么」 纯 Python无 bpy
2.`kind``textured`,贴图放 `assets/textures/``materials.py:14`
`TEXTURE_ROOT`
3. `generate_scene.py` 里用 `material_from_spec(catalog.MATERIALS["<key>"])`
4. **若这个材质在 Cesium 里需要调色,去 `export_cesium.py` 的四张表加**——
见下文,那边按材质名字符串匹配
4. **若这个材质在 Cesium 里需要调色,`cesium` 子契约写在同一个
`MATERIALS` 条目里**。`materials.from_spec()` 会把它序列化到
`material["cesium_export"]`,导出器优先读这个属性
### 颜色是线性 RGB
@@ -160,18 +161,24 @@ tilt_y = TILT_JITTER * math.cos(index * 0.927295)
模型保持在**局部 ENU 坐标系**X 东、Y 北、Z 上),靠伴生 JSON 配合
`Cesium.Transforms.eastNorthUpToFixedFrame` 摆放。
### 四张覆盖表(按材质名字符串)
### Cesium contract
| 表 | 位置 | 作用 |
|---|---|---|
| `EXPORT_TINTS` | `:68` | 往某个颜色混合 |
| `EXPORT_METALLIC_OVERRIDES` | `:80` | 平铺的金属度覆盖 |
| `EXPORT_BASE_COLOR_OVERRIDES` | `:86` | 直接替换基色 |
| `EXPORT_EMISSION_OVERRIDES` | `:95` | 自发光兜底 |
新生成场景的 Cesium 导出调色写在 `catalog.MATERIALS[*]["cesium"]`,由
`materials.from_spec()` 保存成材质自定义属性 `material["cesium_export"]`。导出器打开
`.blend` 后优先读这个属性,不 import `catalog`
⚠️ `export_cesium.py` **不 import `catalog`**,靠材质名字符串匹配。
`catalog.CESIUM_EXPORT` 是**死代码**。改材质名前先读
[模块结构](./module-structure.md#已知现状两个入口靠材质名字符串对接)。
`cesium` 子契约字段:
| 字段 | 作用 |
|---|---|
| `tint` | diffuse 贴图导出前往目标颜色混合 |
| `metallic` | 覆盖导出 PBR metallic |
| `base_color` | 直接替换导出基色,并禁用 diffuse/normal 图 |
| `emission` | 自发光兜底 |
`export_cesium.py` 仍保留 `EXPORT_TINTS``EXPORT_METALLIC_OVERRIDES`
`EXPORT_BASE_COLOR_OVERRIDES``EXPORT_EMISSION_OVERRIDES` 四张按材质名字符串匹配的表,
但它们只是旧 `.blend` 兼容回退。新材质不要只写旧表。
### 为什么新资产总是"发黑"
@@ -181,8 +188,8 @@ tilt_y = TILT_JITTER * math.cos(index * 0.927295)
> 带肋墙面往白混 86%、建筑自发光 0.18。一个没调过的新资产是唯一如实渲染的东西,
> 放在旁边就显得发黑。
所以**加新资产时,"它在 Blender 里看着对"不代表在 Cesium 里对**,必须去四张表里
给它配一份调校。
所以**加新资产时,"它在 Blender 里看着对"不代表在 Cesium 里对**,必须
`catalog.MATERIALS[*]["cesium"]`给它配一份调校。
抠图植被走的是另一套(`FOLIAGE_ALBEDO_GAIN = 2.1` + `FOLIAGE_SATURATION = 1.75`
`:55, 66`),用**增益**而不是 tint——因为那是一张同时装着叶片、树皮、果实的图集

View File

@@ -13,7 +13,7 @@
| 新建模块、挪代码、加一种 OSM 要素 | [模块结构](./module-structure.md) ← **先确认放在哪一层** |
| 改几何构建、材质、实例化、Cesium 调色 | [资产生成](./asset-generation.md) |
| 改 `geom.py` / `osm.py` 或加纯函数 | [测试](./testing.md) |
| 改材质名、动 `MATERIALS` 顺序 | [模块结构 · 材质名对接](./module-structure.md#已知现状两个入口靠材质名字符串对接) |
| 改材质名、动 `MATERIALS` 顺序 | [模块结构 · 材质名对接](./module-structure.md#材质名对接新场景靠自定义属性旧场景靠回退表) |
| 声称"纯重构,产物不变" | [产物一致性指南](../guides/artifact-parity-guide.md) |
---

View File

@@ -135,31 +135,52 @@ argv = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
---
## ⚠️ 已知现状:两个入口靠材质名字符串对接
## 材质名对接:新场景靠自定义属性,旧场景靠回退表
**这是当前实际状态,不是设计目标。改动材质名之前必读。**
`export_cesium.py` **不 import `catalog`**,这是刻意边界:导出器消费 `.blend`
里保存的材质事实,而不是用当前源码里的 catalog 按材质名反查。
`export_cesium.py` **不 import `catalog`**(它只 import
`from osmassets.materials import link_alpha_clip`)。它自己维护四张以**材质名字符串**
为键的覆盖表:
新生成场景的数据流是:
```
catalog.MATERIALS[*]["cesium"] # 纯 Python 数据,无 bpy
materials.from_spec() # 写 material["cesium_export"] JSON 字符串
<area>.blend # 契约随场景文件保存
export_cesium.py # 优先读 material custom property
```
`cesium` 子契约可携带:
| 字段 | 作用 |
|---|---|
| `tint` | diffuse 贴图导出前往目标颜色混合 |
| `metallic` | 覆盖导出 PBR metallic |
| `base_color` | 直接覆盖导出材质 base color并禁用 diffuse/normal 图 |
| `emission` | 设置导出材质自发光 |
为了兼容旧 `.blend``export_cesium.py` 仍保留四张以**材质名字符串**为键的回退表:
| 表 | 位置 |
|---|---|
| `EXPORT_TINTS` | `export_cesium.py:68` |
| `EXPORT_METALLIC_OVERRIDES` | `:80` |
| `EXPORT_BASE_COLOR_OVERRIDES` | `:86` |
| `EXPORT_EMISSION_OVERRIDES` | `:95` |
| `EXPORT_TINTS` | `export_cesium.py` |
| `EXPORT_METALLIC_OVERRIDES` | `export_cesium.py` |
| `EXPORT_BASE_COLOR_OVERRIDES` | `export_cesium.py` |
| `EXPORT_EMISSION_OVERRIDES` | `export_cesium.py` |
后果
约束
- ** `catalog.MATERIALS` 里的 `name` 会静默断开这些覆盖**。没有任何校验,
材质只是悄悄退回未调过的样子
- `catalog.CESIUM_EXPORT``catalog.py:142`**是死代码**——定义了但全仓无人引用。
它是一次未完成的迁移,不要以为改它会生效
- **新材质的 Cesium 调色写在 `catalog.MATERIALS[*]["cesium"]`,不要只加到四张回退表**。
否则新生成的 `.blend` 不会自带契约
- `catalog.py` 仍属纯 Python 层,不能 import `bpy`;序列化发生在 `materials.py`
- `"Office White Metal Facade"` 在四张表里都有,但 `catalog` 里**已无此材质**
`docs/refactor-plan.md` 记为缺陷 D1,本轮只记录不修)
`docs/refactor-plan.md` 记为缺陷 D1)。它只能作为旧 `.blend` 回退兼容存在,
不要迁回新契约源
**改材质名时**四张表 + `catalog.MATERIALS` + `catalog.ROAD_LAYERS` 全部 grep 一遍。
**改材质名时**`catalog.MATERIALS` + `catalog.ROAD_LAYERS` + 四张旧回退表全部
grep 一遍;新生成场景靠 `cesium_export` 属性,旧场景仍靠回退表。
---
@@ -172,8 +193,8 @@ argv = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
| 删掉 `sys.path.insert` 样板或 `# noqa: E402` | Blender 里 import 不到 osmassets |
| 要素模块假设 ring 已裁剪 | 越界几何进场景 |
| 要素模块对退化输入抛异常 | 一个坏多边形中断整片区域 |
| 改材质名只改一处 | Cesium 侧调色静默失效 |
| 以为改 `catalog.CESIUM_EXPORT` 会影响导出 | 它是死代码 |
| 改材质名只改一处 |`.blend` Cesium 回退调色可能静默失效 |
| 只改四张旧回退表,不改 `MATERIALS[*]["cesium"]` | 新 `.blend` 不会携带 Cesium 导出契约 |
---