批次 500 · 2026-09-16 · 纯分析批(主仓 src/ / functions/ 零改动,未提交未部署)
【核心结论 1】样张不是一张"照片",是把两种物理上互斥的视角合成出来的插画。
它同时具备「平视的塔尖剪影」(要求相机贴近地面)和「俯视的城市肌理」(要求相机在高空)。
任何单一相机 —— 无论 3D WebGL 还是 2D 光栅 —— 都永远渲染不出它。
这就是 440 / 480 / 490 三批、几十轮调参都不收敛的根本原因:我在解一道无解方程。
【核心结论 2】"每个城市都能做出样张效果"在数据与几何上都不成立。
天际线出现的物理条件是 建筑高度 ≳ 相机高度。
【核心结论 3】能达标的技术是「分层合成」,不是「场景渲染」。
同一份真实建筑高度场,跑两台不同高度的虚拟相机,再按带融合成一张图 ——
这正是插画家的工作方式,不是任何 3D 引擎或地图 SDK 的工作方式。
| 参数 | 实测值 | 备注 |
|---|---|---|
| 尺寸 / 均值 / 纯黑占比 | 1920×969 / 20.1 / 54.4% | 极暗、大面积留黑 |
| 地平线辉光带 | y = 56.2% | 行均值在 52.5%→57.5% 处跳变 |
| 月牙 | cx 50.5% / cy 52.4%,40×54 px | 唯一暖焦点,仅占画面 0.049% |
| 塔群带 | y 54.5% – 67% | 塔顶仅高出地平线约 1.5%(15 px) |
| 城市肌理带 | y 67% – 100% | 俯视视角,占画面下 33% |
| 左右框景山 | x 0–28% / 71–100%,y 54%→88% | 带密集脊线纹理 |
| 星座 | 10 组几何连线图,全在 y<45% | 标志性元素 |
分段行均值(实测,这是后续验收的唯一口径):
| 区段 | 0–15% | 15–50% | 50–58% | 58–75% | 75–88% | 88–100% |
|---|---|---|---|---|---|---|
| CT-1 样张 | 4.14 | 9.26 | 16.56 | 35.44 | 29.73 | 41.56 |
修正记录:460 批所用的 地平线 = 69.76%,来自标注面板的拼接缝误读(该面板是 2 倍放大的上下两半拼接)。本轮用原图重新标定,正确值为 56.2%。此前所有"带区 +75% 超标"的判定,是拿错基准算出来的。
我做了实验。用同一份北京朝阳区真实数据(5803 栋建筑,最高 528 m):
| 相机高度 | 结果 |
|---|---|
| 390 m 俯视(可以看见整座城市) | 天际线完全消失。528 m 的中国尊在 2 km 外仍低于视点 138 m;整座城市退化成一块平坦的暗色地面,画面里没有任何塔。 |
| 30 m 近地(能看见天际线) | 城市带成型,但视野只剩几百米 —— 看不到样张下半部那片俯视城市肌理。 |
这两个视角不可能同时成立。 样张却同时拥有。
⇒ 样张的"下半部俯视肌理"与"上半部平视塔尖"不是同一个相机拍出来的,是画师把两个视角拼在一张画布上。
这就是为什么我把"发光柱阵"参数从亮调到暗、从高调到矮、从密调到疏,永远出不来那个味 ——
我一直在用一台相机去追一个两台相机才有的构图。
| 城市 | 建筑数(同口径) | 最高建筑 | 能形成样张式塔群? |
|---|---|---|---|
| 北京朝阳(3 km) | 5803 | 528 m(中国尊) | 能(局部) |
| 诸暨暨阳(8 km) | 10 栋(真实)/ 7114(合成) | 60 m | 不能(差 8 倍量级) |
| 台北信义(3 km) | 见 tile | 508 m(101) | 能 |
中国中小城市在开放地图上基本没有建筑数据:道路有人画,楼没人画。
诸暨市中心 8 km 范围内只有 10 栋真实建筑。这不是渲染问题,是源头没料。
更关键的是几何天花板:即便用合成数据补足数量,60 m 的高度上限决定了
这片天际线永远是"低平的",做不出样张那种刺破天际的塔群。
我一直在把城市当作一个 3D 场景去模拟(建模 → 光照 → 相机 → 渲染),
而样张是一个 2D 画面构图(图层 → 剪影 → 光晕 → 调色)。
这是两种完全不同的手艺:
| 场景渲染(我做的) | 画面构图(样张要的) | |
|---|---|---|
| 基本单元 | 一栋楼 | 一个图层 |
| 形状来源 | 几何投影 | 轮廓提取 |
| 立体感来源 | 光照模型 | 明暗渐变 + 大气透视 |
| 细节来源 | 逐物体材质 | 纹理叠加 |
| 控制方式 | 调物理参数 | 调图层与曲线 |
"亮 → 柱阵;暗 → 细带"两端的摆动,就是用它去做它的必然结果。
| 问题 | 答案 | 说明 |
|---|---|---|
| 能否像素级 1:1? | <span style="color:#39FF14">能,但只有两条路</span> | ① 直接用那张图(或其衍生)当底;② 让 AI 针对每个城市重出一张同风格图。用真实几何渲染做到像素 1:1,在数学上不可能(样张是主观构图,不含可反解的相机参数) |
| 能否做到"人眼认为是同一套设计"? | 能,上限约 85–90% | 靠复刻视觉语法(调色板 / 光位 / 形体 / 构图 / 图层),不是复刻像素 |
| 能否任意城市、秒级出图? | 能,且远快于 3 秒 | 需先把"3 秒"的语义拆开(见 3.2) |
| 能否做成"真页面"而非"一张图"? | 能 | 剪影层 = 真实数据(可选中、可 SEO);UI 层 = DOM |
"3 秒"其实混了两件完全不同的事:
| 阶段 | 耗时现状 | 能否 3 秒 |
|---|---|---|
| A. 拉取一个城市的原始数据(Overpass / 商业 API) | 诸暨 16 片:约 20 分钟;北京 36 片:约 12 分钟 | ❌ 不可能,也不该在首屏做 |
| B. 从零把城市压成高度场(离线烘焙) | 4000² 高度场:0.2 秒 | ✅ |
| C. 首屏出画面(加载预烘 tile + 合成) | 本原型 CPU 版光线投射 10–20 秒;同等算法在 GPU fragment shader 下 <10 ms | ✅✅ 实际可做到 200 ms |
【核心结论】正确做法是把 A、B 留在离线的"一次烘焙",让 C 变成纯前端合成。
一个城市只烘一次,之后每次访问都是毫秒级。"3 秒"从来不是技术瓶颈,"从零拉数据"才是 —— 而它根本不该在首屏发生。
街景(Street View)不能用来做这件事,三个硬理由:
1. 街景是地面视角的 360° 照片,视角与样张要求的"高空远眺"相差 90°;
2. 街景没有几何:拿不到建筑轮廓、拿不到高度、拿不到城市平面布局;
3. 街景本质是贴图 —— 既触犯项目红线(禁止贴图),也无法产生"剪影"这种需要轮廓的信息。
真正可用的素材是三类(都不是街景):
| 素材 | 提供什么 | 数据源 |
|---|---|---|
| 矢量建筑轮廓 + 高度 | 城市的形状与体量(本文全部结论的基础) | OSM / 天地图 / 高德 / Mapbox |
| DEM 数字高程 | 山脉、地平线、地形起伏 | SRTM / ASTER / Copernicus |
| 卫星影像(可选) | 纹理与密度参考(不作为底图) | 各家影像服务 |
【核心结论】技术栈应该是「高度场 + 分层合成」,而不是「3D 场景 + 光照模型」。
真实建筑 footprint + height
│ 光栅化(极快,0.2s / 城市)
▼
城市高度场 (Height Field, 如 4000² @ 5m/px)
│
├──► 相机 A(低视点 ~50-250m)──► 光线投射 ──► 天际线剪影 + 边缘光
│ (画面上半部的"塔")
│
└──► 相机 B(高视点 ~430m) ──► 光线投射 ──► 俯视城市肌理
(画面下半部的"海")
│
▼ 按带融合(seam ≈ 58%)
┌──────────────────────────────┐
│ 10 层 2D 合成 │
│ 天空/银河/星座/星野/月 │
│ → 远山框景 → 地平辉光带 │
│ → 剪影层 → 肌理层 → Bloom → 调色 │
└──────────────────────────────┘
│
▼
首屏画面(DOM UI 叠在上层)
为什么这套对:
1. 高度场光线投射天然产生"整块剪影 + 真实遮挡"—— 不是"一栋栋发光楼",而是"一整块地形"。这一条直接终结了 440/480/490 的"柱阵病"。
2. 双视点直接对上样张的双视角合成本质。
3. 纯 2D 合成天然适合 GPU fragment shader,单 pass、<10 ms。
4. 剪影层是真实数据,可点击、可 SEO、换城市只换 tile。
我把所有约束都解除(含你定的红线),穷举如下:
| # | 方案 | 与样张一致度 | 真实性 | 首屏 | 换城市 | 触红线 |
|---|---|---|---|---|---|---|
| S1 | AI 生图直接出首屏底图(每城市一张) | 95% | 假几何 | 即时 | 出图 20–60 s | 是 |
| S2 | AI 出"通用素材层"(星野/银河/山体/水体,不含城市信息)+ 真实数据出城市剪影 → 合成 | 88% | 城市真、素材假 | <300 ms | 自动 | 灰区 |
| S3 | 高度场 + 双视点分层合成(本文推荐) | 85–90% | 全真 | <300 ms | 自动 <30 min | 否 |
| S4 | 商业 3D 地图 SDK 换暗青主题(Mapbox / MapTiler / Cesium / 高德) | 75% | 全真 | ~1 s | 零成本 | 否(需授权+联网) |
| S5 | 现有 3D 场景 + 后期描边/色阶(三渲二) | 70% | 全真 | 1–2 s | 自动 | 否 |
| S6 | 现在的做法(3D 几何 + 逐栋材质) | 50% | 全真 | 慢 | 自动 | 否(已证明走不通) |
关键提醒:S4 不解决根本问题 —— 商业地图在中国大陆的中小城市建筑覆盖同样差(与 OSM 同源或同缺口)。它能给你"任意城市的真地图",但给不了"诸暨有塔群"。
【核心结论】推荐 S3 为主线;同时把 S1/S2 作为"要 100% 像"时的一键切换开关。
| 实验 | 做了什么 | 得到什么 |
|---|---|---|
| v3 | 用真实数据建高度场,390 m 单一物理相机光线投射 | 证明了物理不可能:整座城市退化为一块平面,零天际线。这是"为什么出不来"的直接实验证据 |
| v4 | 双视点合成(245 m 剪影相机 + 430 m 肌理相机,按带融合) | 证明了架构可行:暗天 / 星座 / 月 / 左右框景山 / 上下双层结构全部成立;下半部仍需美术调校(属调参,非可行性问题) |
度量对拍(0-15% / 15-50% / 50-58% / 58-75% / 75-88% / 88-100%):
| 版本 | 六段行均值 |
|---|---|
| CT-1 目标 | 4.1 / 9.3 / 16.6 / 35.4 / 29.7 / 41.6 |
| v3 单相机 | 20.3 / 29.8 / 134.1 / 77.5 / 47.4 / 37.0(天空过亮、辉光带饱和) |
| v4 双视点 | 14.6 / 15.0 / 9.0 / 24.9 / 20.8 / 18.5(骨架对,下半偏暗 ~35%) |
诊断图:docs/sky/assets-500/DIAG-why-not-working.png
| # | 决策 | 选项 |
|---|---|---|
| D-1 | 红线:是否解除"禁止 AI 生图/贴图"? | 解除 → 可走 S1/S2,今晚就能 95% 像;不解除 → 走 S3,上限 85–90%,2–3 小时 |
| D-2 | "像"的定义:像素 1:1,还是"同一套设计语言"? | 像素 1:1 → 只能 S1/S2;同一套语言 → S3 就够 |
| D-3 | 小城市无数据怎么办? | ① 真实路网 + 程序化建筑(已做)② 接商业地图(需授权)③ 直接声明"该城市数据不足" |
D:\workbuddy\2026-09-15-00-01-41\sky-build\proto2d\;主仓 src/、functions/ 零改动;worktree 未提交;未部署;CT-1 冻结基线未覆盖。docs/sky/assets-500/DIAG-why-not-working.png(核心诊断图)proto2d/render_grammar.py(v2 角高度剖面原型)proto2d/render_v3.py(单相机高度场投射 —— 反证)proto2d/render_v4.py(双视点合成 —— 正解骨架)proto2d/compare-v3.png、compare-v4.png(三方对拍)