Files
osmWorkflow/docs/changelog.md

136 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Changelog
## 2026-08-03
- 初始化 Trellis 项目规范,把 `trellis init` 误生成的 frontend spec 替换为本项目真实的
`pipeline` / `blender` / `preview` / `config` 四层规范,并把跨层 parity、图层顺序、
外部工具 staging、纯 Python / bpy 边界等反直觉约定固化到 `.trellis/spec/`
- 完成 Cesium 材质导出契约化:`catalog.MATERIALS[*]["cesium"]` 现在由
`materials.from_spec()` 写入 `.blend` 材质自定义属性 `material["cesium_export"]`
`export_cesium.py` 优先读取该属性;旧四张材质名表仅保留为旧 `.blend` 回退路径。
parity before/after 只有 `.blend` 新增 `props.cesium_export``.blend` bytes 变化,
无 GLB/material/metadata 结构漂移。
- 收尾临时 `osmassets` 重构施工计划P0/P1/P3 的长期知识已经进入 changelog 和 Trellis spec
P2 仍是后续重构方向(`building` / `fountain` / `roads` 仍在 `generate_scene.py` 里,
尚未形成完整 `features/` 注册表)。删除临时计划文件,避免继续传播旧行号和
`catalog.CESIUM_EXPORT` 死代码等过期事实。
## 2026-07-31远看发黑的真正原因反照率没被提亮
(二)里加的 emissive 提到 0.8 仍然发黑。原因是 emissive 乘的是本来就很暗的
反照率0.8 × 深绿 ≈ sRGB `[0.22, 0.31, 0.11]`,还是暗的。**要提的是反照率本身。**
用户给的 Cesium 截图定位了问题:草是亮黄绿、建筑近白、路面浅灰,只有树是暗的。
这棵树的图集叶片本来就是深绿——绿色系像素均值 sRGB `[0.249, 0.35, 0.12]`。按真实
反照率渲染是对的,但**场景里其他材质都被手工提亮过**`EXPORT_TINTS` 草 0.72、
带肋墙面 0.86`EXPORT_EMISSION_OVERRIDES` 建筑 0.18),全是针对 Cesium 偏白的
默认光照调出来的。新资产没调过,是唯一一个如实渲染的东西,放在旁边就显得发黑。
- 新增 `FOLIAGE_ALBEDO_GAIN = 2.1`,在抠图植被的 dilate 那一遍里顺带乘上去。
用增益而不是 tint其他材质是单一表面所以 tint 合适,而这是一张同时装着叶片、
树皮、果实的图集,往绿色混会把树干也染绿。缩放保留色相关系,只是把整体抬到和
邻居一样的曝光。叶片 sRGB `[0.249, 0.35, 0.12]``[0.36, 0.50, 0.18]`
过曝到纯白的像素只占 0.4%
- `FOLIAGE_EMISSION` 回调到 0.25:它的职责只是给背光面兜底,不是主要提亮手段
- 增益之后远看仍偏灰绿,再加 `FOLIAGE_SATURATION = 1.75`,绕各像素自身
Rec.709 亮度做饱和度拉伸。这张图集本来就偏灰(平均饱和度 0.22),而远看时
mip 会把叶片、树皮和缝隙混在一起,越小越往中性靠。绕亮度拉伸能把叶片推绿而
基本不动本来就中性的部分,也没有绿色 tint 强加给树干的色相偏移——树皮只是变
暖一点。叶片 sRGB → `[0.262, 0.529, 0.021]`,整体饱和度 0.22 → 0.34
- 新增 `triangulate_mesh()``export_tangents` 打开后刷了 55 行
「切向空间只能只算三角/四边形」——`MeshBatch` 建的 OSM 轮廓都是 n-gon
Blender 只能给三角/四边形算切线。glTF 本来就只有三角形,导出时无论如何都会
三角化,所以提前做不改变任何一个输出三角形(实测三角数 51719 前后一致),
但切线从 49/102 变成 102/102警告归零
排查中被数据排除的假设,记下来免得重走:贴图颜色全链路逐位一致(不是 gamma
模拟 mip 链可见像素亮度 0.127→0.124(不是 mipmap法线贴图抠图区是干净平面法线
(不是法线污染);把导出的 GLB 重新导入 Blender 渲染,树是正常的(文件没问题)。
## 2026-07-31远看整棵树发黑
黑色色块修掉后Cesium 里近看正常、远看整棵树是暗色块。逐项排查:
- 贴图颜色全链路无偏移:源 4k / 降采样 2k / GLB 里导出的 PNGopaque 均值都是 sRGB `[0.409, 0.406, 0.362]`,不是 gamma 问题
- 模拟 GPU mip 链(逐级 box 降采样,按 0.5 cutoff 取可见像素):可见像素亮度 mip0→mip6 只从 0.127 变到 0.124,覆盖率稳定在 0.42,不是 mipmap 变暗
- 法线贴图抠图区域是干净的平面法线 `[0.494, 0.512, 0.988]`无黑像素mip 后趋于更平,不是法线污染
真实原因是**缺少 emissive 补偿**。预览页没有配置任何环境贴图(`skyBox` / `skyAtmosphere` / `sun` 全部关闭Cesium 只剩一个很弱的默认球谐环境光,所以太阳直射不到的面接近全黑——这正是 `EXPORT_EMISSION_OVERRIDES` 存在的原因,建筑 0.18、程序化树冠 0.015~0.02。树冠绝大部分是背光的叶片卡片远看整体塌成一团暗色而近看能看到向阳面所以还行。apple 材质不在那张表里,一点补偿都没有。
- 抠图植被改为把 diffuse 接回 Emission Color强度 `FOLIAGE_EMISSION = 0.22`。用带贴图的自发光而不是平坦颜色:常量会把树干也染成叶子绿,而这样每个像素的下限是它自身反照率的一个比例。不增加字节,导出器让 `emissiveTexture` 指向 base color 已经在用的那张图
- glTF 导出打开 `export_tangents`apple 材质有法线贴图但图元没有 TANGENT缺失时由渲染器自行推导切线而在双面薄片叶子卡上这个推导不可靠。全场景 49/102 个图元带上切线顺带修正建筑法线贴图GLB +0.83MB
如果远处仍偏暗,调 `export_cesium.py``FOLIAGE_EMISSION` 一个常量即可。
## 2026-07-31
- 树渲染改用两个第三方模型,`tree_style` 新增 `apple` / `fattree`
- `apple` — SpeedTree Red Delicious4475 tris叶片 alpha 抠图 + 法线贴图4k 贴图降采样为 2k
- `fattree` — 低面数卡通树2238 tris实体几何
- 高度不再用魔数缩放,改为按模型自身包围盒归一化到目标高度,树根落在 z=0
- 每棵树按序号做确定性抖动:缩放 ±14%、黄金角偏航、±3° 倾斜,成排的行道树不再是同一棵树盖章
- 移除 `polyhaven` 树样式和 island_tree_01 资产76MB+ `blender/tools/ingest_tree.py`。该样式 append 的 `*_LOD1` 对象并不是完整的树:枝干只有 0.41 单位高,叶片是挂在原点下方的平面簇,原本是给源文件里的几何节点散布用的,直接种下去只有树枝
- 修复 Cesium 导出丢失 alpha 抠图:`make_export_material` 原本把 Alpha 恒定写死为 1.0,叶片卡片整块导出,而 SpeedTree 图集抠掉的区域是纯黑,在 Cesium 里表现为黑色色块
- Blender 4.2 起 glTF 导出不再读 `blend_method`(仍可写但已失效,写 `CLIP` 读回来是 `HASHED`),改为从节点树推断 alpha 模式。新增 `materials.link_alpha_clip()` 构造导出器识别的 `1 - (alpha < cutoff)` 节点形状,得到 `alphaMode=MASK`,同时 EEVEE 里也变成硬边抠图
- 新增 `alpha_dilated_image()`:把不透明像素的颜色向抠图区域外扩 8 圈。97.5% 的透明像素是纯黑Cesium 生成 mipmap 时会把黑色平均进叶片边缘。叶片边缘相邻的纯黑像素占比从 10.3% 降到 0.6%
- 修复导出器对实例化网格重复包装材质:材质槽在 mesh 上181 棵树共享一个 datablock第一棵替换后其余 180 棵会把结果再包一次,产生 `Cesium Cesium Cesium ...` 的材质名且烘焙图缓存按材质名索引每轮都会再嵌一份同样的贴图。GLB 22.46MB → 20.76MBmaterials 270 → 23
- `source_alpha_clipped()` 同时要求「材质连了 Alpha」和「贴图确实有抠图」shrub_02 从 glTF 带进来一个 Math 节点接在 Alpha 上,但它的 JPEG 贴图 alpha 全是 1.0,只判断前者会把它误判为抠图材质,白白重编码成 1.2MB PNG 并让 Cesium 对 270 丛草做 alpha test
- 场景新增 `tree_style` / `tree_style_used` 属性;模型资产缺失时自动回落到 `natural`
## 2026-07-30
- 重构 Blender 脚本为 `osmassets` 包:`generate_scene.py` 从 1271 行缩减到 826 行 (-35%),纯函数可脱离 Blender 测试 (42 个 unittest)
- `osm.py` — OSM 解析 / Projector / parse_height无 bpy
- `geom.py` — 平面几何纯函数(无 bpy
- `materials.py` — Blender 材质创建
- `mesh.py` — MeshBatch / prism / roof / polyline
- `catalog.py` — 道路图层和材质规格的唯一定义源,含 cesium 导出参数
- 要素注册表:`water.py` / `grass.py` / `scrub.py` / `tree.py`,各导出一个 `assemble()` 函数
- 新增 parity 工具链:`scene_digest.py` + `glb-digest.js` + `parity.js`,两区域全 PARITY OK
- 接入 Poly Haven island_tree_01 真实扫描树模型:`tree_style` 新增 `polyhaven` 选项(已于 2026-07-31 移除,见上)
- 新增 `blender/tools/ingest_tree.py` 用于离线减面导出树模型(已于 2026-07-31 移除)
- `nantaizi-lake-innovation-valley` 配置默认切换为 `treeStyle: polyhaven`(现为 `apple`
## 2026-07-28
- 新增 `reimport` 阶段(`scripts/reimport-gpkg.js`),把 QGIS 手工修正过的 `<area-id>.gpkg` 回导为 `osm2streets_web_out/*.geojson` 并重建 `osm2streets_scene.geojson` / `osm2streets_scene_style.json`。手工修正流程从「`ogr2ogr` 循环 + 内联 node 脚本 + `npm run build`」三步压缩为一条命令:
```bash
npm run build -- --config config/areas/<area-id>.json --stages reimport,blender,cesium
```
- `reimport` 先把全部图层导出到临时目录并逐个校验,全部通过才写回输出目录:`ogr2ogr` 对不存在的图层退出码非 0 但仍会留下 0 字节文件,逐图层直接覆盖会静默损坏数据。
- `intermediates` 与 `reimport` 同时指定时直接报错:前者会用 OSM 重建 GeoPackage正好抹掉后者要读回的手工修改。`reimport` 不含在 `all` 中。
- 新增 `scripts/lib/scene-layers.js` 作为 9 个渲染图层的唯一定义源id、`z_index`、配色、描边宽度)。此前该表在合并场景、场景样式 JSON、生成的 QGIS 工程、README 手工流程中各有一份副本,改一处漏其余会导致图层叠放顺序错误并流入 Blender/Cesium。构建产物GeoJSON、GeoPackage、`.qgz` 符号、样式 JSON与改动前逐字节一致。
## 2026-07-27
- 实验分支新增 Cesium 车辆巡航预览:从 OSM 可行驶 `highway` 提取 bounds 内路线,输出 `<area-id>-vehicle-route.json`,并在预览页中驱动车辆循环移动。
- 巡航路线从道路中心线向右偏移约 1.3 米,车辆模型改为无 logo 的轻量预览车。
- 车辆巡航预览支持多辆车同时行驶,并通过 `Vehicle` 下拉框选择 Follow 目标。
- 将项目主入口重构为区域资产管线:`scripts/build-area.js`。
- 新增 `config/areas/nantaizi-lake-innovation-valley.json` 和 `config/areas/hanyang-block.json`,支持按 OSM 输入生成独立输出目录。
- `npm run build` 现在默认走区域资产管线;旧 QGIS 管线保留为 `npm run build:qgis`。
- `cesium` 阶段会生成 `<area-id>-cesium-preview.html` 本地预览页。
- 修复 Blender 脚本对 `--tree-style` 和 `--office-overrides` 这类连字符参数的解析。
## 2026-07-24
- Blender 场景生成器通用化:`generate_nantaizi.py` → `generate_scene.py`
- 去除所有硬编码默认路径(--osm / --geojson / --output / --render 均为 CLI 必传)
- `--geojson` 改为可选参数,不传时回退到 OSM highway 折线
- `--office-overrides` 替代硬编码的 `OFFICE_OVERRIDE_WAY_IDS`
- `export_cesium.py` 同样去除硬编码默认路径CLI 参数改为必传
- `config/default.json` 路径改用占位符 `/absolute/path/to/...`
- `config/examples/template.json` 新增 `layerPrefix` 和 `blender` 配置块
- `scripts/build-osm2streets-qgis.js` 新增 `layerPrefix` 配置支持
- 包名改为 `osm-gis-pipeline`
- 文档全面更新为中文通用描述
## 2026-07-17
- Added configurable input/output paths through JSON config files.
- Added [config/default.json](/Users/que01/osm2streets-qgis-workflow/config/default.json) for `/Users/que01/Downloads/osm.xml`.
- Added [config/hanyang-block.json](/Users/que01/osm2streets-qgis-workflow/config/hanyang-block.json) for `/Users/que01/Desktop/汉阳区区块.osm`.
- Added [config/examples/template.json](/Users/que01/osm2streets-qgis-workflow/config/examples/template.json) for new areas.
- Updated OSM node coordinate parsing to support both single-quoted and double-quoted XML attributes.
- Verified QGIS outputs for both a smaller Overpass-style XML input and a larger JOSM-generated `.osm` input.