Skip to content

园区孪生复刻:从一张鸟瞰效果图到全场景几何 ​

初始化中…

前面几篇都是"先有模型再看画面",这篇倒过来:只给一张鸟瞰效果图,场景从提示词里长出来。图我只当建模蓝本用,页面上不放原图,几何、材质、天空全部代码生成——照着别人的效果图练读图和落地的手,但不搬运对方的产物。现在这套几何不止是能看:点任何一栋楼、一段路,能问出它多大、几层、多少建筑面积。

我从图上读到的信息 ​

  • 四个片区:左上是成片的蓝白色大跨厂房;中部是低密度红砖研发楼群,屋顶带绿化、橙色压顶、青色采光顶,而且是围合庭院的布局;右侧是一栋白色锯齿折板屋面的大会场;中央偏下有一个圆形构筑物,绿顶加橙色环。
  • 轴线是斜的:建筑长边跟画面边框成 20° 左右夹角,不是正南北。
  • 路网与交通:环形沥青路,路口有斑马线,路边停着和跑着大量小车。
  • 绿化与人流:行道树沿路成排,外围是成片树林,中央广场上有密集的人。
  • 大气:鸟瞰 45°,远景明显被雾霭吃掉,光线偏暖、从一侧来。

交给 AI 的提示词(我固定分四组写) ​

总体与尺度

  1. 纯程序化生成,禁止引入任何外部模型、贴图、HDR 或图片;天空用一段 canvas 线性渐变,其余全是几何加材质参数。
  2. 尺寸按米给死:厂房单跨 24 m、檐口 9 m、屋脊起坡 3.2 m、栋长 88 m;研发楼层高 3.9 m、3~5 层;会展折板 22 折、每折 6 m、屋面总长 132 m;园区净距约 720 × 640 m。
  3. 建筑轴线斜置 0.32 rad,整个园区挂在同一个 Group 下旋转,不许逐栋手算旋转后的坐标。
  4. 布局随机但必须确定性:用固定种子的线性同余随机数,刷新多少次,树、车、人的位置都完全一致。

分区

  1. A 区西北:2 列 × 3 行共 6 栋大跨厂房,栋长 88 m、每栋 2 跨人字坡(面宽 48 m),行距 68 m 留出 20 m 间距,脊线通长,每跨一条采光带。坡屋面用带倾角的实例化板,不许用贴图假装坡度。
  2. B 区中部:4 组围合庭院,每组 4 栋研发楼。长边 92~112 m、短边 58~70 m,四面围合留出中间绿地;陶土红墙 + 橙色女儿墙压顶 + 屋顶绿化 + 青色采光顶,压顶要做成四边圈口,每层四面各一条窗带。
  3. 中央圆形构筑物:半径 13 m,圆柱主体 + 绿顶 + 橙压顶环 + 锥形采光顶,落在独立广场上。
  4. C 区东侧:锯齿折板会展,折数 = 楼长 / 每折宽度,每折一条缓坡白板配一道陡面玻璃,折板要铺满通长;旁边另有一栋白色斜顶配套楼。
  5. 路网 9 条(外环 4 + 东西主街 3 + 南北纵街 2),每条带车道虚线,6 处路口斑马线;行道树沿路每 26 m 一棵,另有 4 片随机树林;广场人流用胶囊体示意。
  6. 46 台车沿两条矩形环路跑,取点用周长参数化,横向偏移要按所在边的朝向旋转,不许出现横在路中间的车。

灯光与大气

  1. 暖色斜阳(0xffe6c0,3.1)从西偏上打下来,阴影相机左右上下各 ±380 覆盖全场;补一道半球光和一道冷色反弹光照顾背光面。
  2. FogExp2 密度 0.0008,颜色贴天空下缘,让远处建筑自然退进雾里,做出效果图那种空气感。
  3. ACESFilmic 色调映射、exposure 1.06、sRGB 输出。

镜头与读数

  1. 64 秒一轮:四个聚焦段(厂房 / 研发 / 会展 / 全域鸟瞰)各自给中心、视距、高度,鸟瞰段要能装下全场;环绕角一整圈对齐一轮,段间 smoothstep 过渡,每段只飞前 35%、剩下 65% 停在原地环绕。
  2. 零控件,状态全写进左下角文字:聚焦区与环绕角、各区体量、屋顶绿化面积、采光带条数、乔木株数、车辆与人流数、三角面、帧耗时。
  3. 拖拽随时接管,5 秒后指数缓动回巡游;组件卸载时几何、材质、贴图、控制器全部释放。
  4. 构件要有台账:属性在生成几何之前登记,实例数据里带归属字段,不许靠 push 顺序反推是哪一栋;点构件出名称与尺寸,点空白收起,点中即停巡航并把视点挪过去。

实现里几个值得记的点 ​

局部坐标不能直接喂给相机。 园区整体旋转了 0.32 rad,我写的聚焦中心是那个 Group 内部的本地坐标,而 camera.position 和 controls.target 吃的是世界坐标。直接把本地值给相机,镜头会对准建筑旁边的空地。必须先 park.localToWorld(v);因为环绕是整圈,绕转换后的中心在世界空间旋转,跟在本地空间绕原点旋转是等价的。

坡屋面只能用旋转分量,不能事后补。 实例化板的倾角一开始被我塞进自定义字段,然后指望批量函数认得它,结果 36 块坡面全是平的,只能再遍历一遍覆写矩阵。正确做法是批量函数就统一收 rx / ry / rz,倾角直接写进构造数据里。

先算净距,再摆房子。 厂房排布返工了两轮。第一版按行距 80 m 排,四跨厂房光宽度就 96 m,两排直接咬在一起;改成三跨 72 m 面宽配 74 m 行距,只留 2 m 缝,鸟瞰里六栋糊成两大块白饼,看着像一个巨厅而不是六栋独立厂房。最后退回到“面宽必须明显小于行距”:两跨 48 m 面宽、68 m 行距,缝宽 20 m,截图里才认出是一栋栋房子。这类碰撞在鸟瞰镜头下不一定看得见,但街景机位一贴近就露馅。

折数不能拍脑袋。 会展我写的是“8 折、每折 5.4 m”,但楼长 132 m,8 折只铺了 43 m——截图里看到的是前半截锯齿、后半截一大块白平屋顶。折板这类重复构件得反过来算:先定总长,再除每折宽度,得到 22 折。顺便把“每折”重做成一条缓坡白板加一道陡面玻璃,比原来单纯把板子正负转一下更像锯齿。

压顶是一块板还是一圈边。 女儿墙压顶我一开始按整块板生成,平面尺寸跟楼栋一样大,结果从上面看下去,橙色压顶把屋顶绿化全盖死了——HUD 上写着两万一千多 m² 绿化,画面里一点绿都看不到。压顶得拆成四边圈口(两条长边加两条短边),绿化板留在圈口以内。同类问题还有窗带:只给两个面开,山墙就变成一整面空墙。

停留时长得按“能不能看完一个区”定。 第一版每段用 (k-0.2)/0.5 做缓动,飞过去占 70%、停住只剩 4.8 秒,一眨眼就换区了;而且环绕角一直在走,真正能认形体的窗口更短。改成 (k-0.15)/0.35 后,每段 16 秒里飞 8 秒、停 8 秒,一个区能看完。

读数不能提前报下一个区的名字。 HUD 里的 cur 是按时间分段取的,飞过去的几秒里标签已经跳到“全域鸟瞰”,而相机还停在会展区上方,看的人以为读数错了。现在 local 不到 0.5 时写“转场 → 全域鸟瞰”,到位了才写“聚焦”。同理,视距那一列在飞行途中是从上一段插值过来的,它跟标签不匹配是正常的,因为标签现在说的是“去哪”而不是“在哪”。

鸟瞰机位得按视角反推。 第一版全域鸟瞰给到视距 560 m、高 330 m,而 40° 竖向视野在这个距离上只能罩住 400 多米,园区净距 720 × 640 m,画面里永远缺一个角。把视距拉到 860 m、高 540 m 才装得下;同时雾密度从 0.0011 降到 0.0008,不然远端建筑会整片化进雾里看不出形体;最底下那片地台也从 1400 m 扩到 2600 m,免得鸟瞰时看见场地边界。

读数要跟画面对得上。 HUD 里屋顶绿化面积是把每块绿化板的实例尺寸累加出来的,跟真正铺上去的是同一份数据,所以不会出现"写着 8000 m²、画面里只有 2000"的情况。三角面同理取渲染器每帧统计值,含实例化与视域剔除。

薄地台不要留缝隙。 路面、草皮、广场都是几厘米厚的板,最底下那片草地最初放在 -0.18 m,建筑从 0 起,贴近看会发现楼悬在空中一条缝。改成地台顶面正好压在 0 附近,上面各层依次抬 0.02~0.06 m 避让 z-fighting。

点选高亮不能靠改颜色。 第一版按常见做法改材质色,但 InstancedMesh 整份共用一个材质,一改就整片研发楼一起变色。退一步用 setColorAt 只动被点的那个实例,结果更糟——instanceColor 是材质色的乘数,不是替换色:陶土红乘 2.2 变成橙红,深色沥青乘完还是黑的,等于路面根本选不中;更坑的是 setColorAt 在 instanceColor 还是 null 时新建的数组全为 0,不先给所有实例填一遍白,其余实例会当场全黑。最后改成描边:单位盒的 EdgesGeometry 只建一份共享,每个实例把自身矩阵乘上父级世界矩阵直接摆位,单体构件用 Box3Helper 合并出一个包围盒。同一个构件的墙体、屋面板、采光带、窗带按归属一起框,点哪块板都认整栋。

点选和拖视角得分开。 pointerdown 就当拾取的话,转一次镜头会顺手选中一个构件。现在记下按下的坐标与时刻,松手时位移超过 6 px 或按住超过 450 ms 直接忽略。点中还要把巡航停住并把 controls.target 挪到该构件,否则镜头继续飞,刚点中的东西转眼出画。

按交付要求核对 ​

要求实际做到判定
零外部素材天空为 canvas 渐变,模型全部程序生成达成
尺寸按米给死24 / 9 / 3.2 / 3.9 / 6 / 132 均写进常量达成
斜向轴线园区整体 -0.32 rad,镜头坐标已做世界换算达成
四区齐备厂房 6 栋、研发 16 栋、圆形构筑物、会展 22 折 + 配套楼达成
围合庭院4 组 × 4 栋,中间绿地独立铺装达成
路网与标线9 条路 + 车道虚线 + 6 处斑马线达成
动态车流46 台车沿两条矩形环路双向跑达成
大气雾霭FogExp2 0.0008 贴合天空下缘色达成
鸟瞰装得下全场视距 860 m / 高 540 m,四区入画达成
文字读数无控件五项读数,页面上没有任何按钮达成
构件属性台账34 个构件,点选出名称与尺寸、层数、面积,属性由建模数据现算达成
点选描边高亮整构件一起框,拖视角与长按不误选达成
卸载清理几何、材质、贴图、控制器全部释放达成

已知不足 ​

  • 形制只到"体量级"。 会展只有折板屋面形式,没有内部大跨结构与看台;研发楼的入口、雨棚、空调机位都没做;效果图里那些弧形和斜切角全部简化成矩形。
  • 动态元素都是示意。 人是不动的胶囊体,车只有一个盒子没有轮和窗,树是二十面体加圆柱,风、水、灯光变化一概没有。
  • 阴影精度不够。 单张 2048 覆盖 760 m,一个 texel 约 0.37 m,近看树影和窗带会糊,要清晰得上分级阴影。
  • 没有 LOD 与遮挡剔除。 全场一镜到底同一精度,真要放大到几百栋就得补分层细节与实例剔除。
  • 后台标签页里巡游会几乎停住。 帧间时间上限封在 0.05 秒是为了防卡顿后镜头瞬移,代价是浏览器把标签页限到每秒一帧时,一轮 64 秒的巡游实际走得极慢。切回前台就恢复正常,但要是把它当大屏常驻页面用,得改成按真实时间推进。
  • 随机种子是写死的。 换种子会整场重排,但没有做"按真实图纸定位"的接口,所以这仍是效果图复刻,不是真实园区孪生。台账里的尺寸也是从几何反推出来的,只能保证跟画面对得上,不代表真实资产。
  • 台账只到"点一下看一眼"。 没有搜索、清单、筛选、显隐,构件名还是 A5#、B4-西# 这种排位编号而不是真实编号;而且站内合规闸禁止表单元素,搜索框、勾选框这类控件在本页做不了,只能走点击拾取。

本站所有 3D 孪生场景、可视化系统均为个人技术实验 Demo,仅用于技术学习与效果展示,不属于对外运营平台,不提供任何商业服务。

本站为个人技术展示网站,仅用于个人研发作品、3D 数字孪生技术学习展示,无任何经营性服务、无社区互动、不对外提供商业服务。

本站为个人技术展示网站,仅用于个人研发作品、3D 数字孪生技术学习展示,无任何经营性服务、无社区互动、不对外提供商业服务。

蜀ICP备2026068005号-1|个人 3D 数字孪生技术研发展示站