Files
osmWorkflow/docs/changelog.md
que01 2139990818 feat: 树渲染改用 apple/fattree 模型,修复 Cesium alpha 抠图丢失
tree_style 新增 apple(SpeedTree Red Delicious,4475 tris,alpha 抠图叶片
+ 法线贴图)和 fattree(低面数卡通树,2238 tris,实体几何)。

高度改为按模型自身包围盒归一化到目标高度,树根落在 z=0,不再用魔数;
每棵树按序号做确定性抖动(缩放 ±14%、黄金角偏航、±3° 倾斜),
tree_row 采样高度全部相同,不抖动就是同一棵树盖章 156 次。

移除 polyhaven 样式和 island_tree_01 资产(76MB)+ ingest_tree.py:
该样式 append 的 *_LOD1 并不是完整的树,枝干只有 0.41 单位高,叶片是
挂在原点下方的平面簇,本是给源文件几何节点散布用的碎片。

Cesium 侧修三处:

- make_export_material 把 Alpha 恒定写死为 1.0,叶片卡片整块导出,而
  SpeedTree 图集抠掉的区域是纯黑,在 Cesium 里就是黑色色块。
- Blender 4.2 起 glTF 导出不再读 blend_method(仍可写但已失效,写 CLIP
  读回来是 HASHED),改为从节点树推断 alpha 模式,alpha 直连 BSDF 会落到
  BLEND。新增 materials.link_alpha_clip() 构造导出器识别的
  1 - (alpha < cutoff) 结构,得到 alphaMode=MASK。
- 新增 alpha_dilated_image():把不透明像素颜色向抠图区域外扩 8 圈,
  避免 mipmap 把黑色平均进叶缘。叶缘相邻的纯黑像素 10.3% → 0.6%。

另修两个既有 bug:

- 材质槽在 mesh 上,181 棵树共享一个 datablock,第一棵替换后其余会把结果
  再包一层,产生 Cesium Cesium Cesium... 的材质名;烘焙图缓存按材质名索引,
  每轮再嵌一份同样的贴图。GLB 22.46MB → 20.76MB,materials 270 → 23。
- shrub_02 从 glTF 带进来一个 Math 节点接在 Alpha 上,但其 JPEG 贴图 alpha
  全是 1.0,只判断「连了 Alpha」会误判为抠图材质。

模型资产为第三方素材,已 gitignore,缺失时回落到 natural;
来源见 assets/models/SOURCES.md。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-31 11:30:16 +08:00

74 lines
6.9 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-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.