从平面到三维:机房设计方案的三维校核与 WebGPU 渲染实践
摘要:平面图能表达尺寸,但表达不了遮挡、净高与空间关系——封闭通道端门会不会挡住运维通道、桥架会不会压到设备、吊顶与架空地板吃掉多少净高,这些问题在二维图上需要脑补。DCDesigner 的 3D 视图由 2D 数据实时派生,支持实景/素模两种风格、对象隔离与编号浮标,可导出 8192px 全景图。本文说明它的定位、校核用法与渲染实现。一、为什么平面图之后还需要 3D
机房设计与工勘里,有几类问题天然是三维的:
- 空间关系:封闭通道的端门上方封窗、门扇高度、机柜顶到吊顶/桥架的余量;
- 遮挡关系:高墙、整排机柜、桥架挡住视线,现场核对时「看不见的地方」往往就是漏项的地方;
- 体量与观感:向非技术角色(甲方、决策者)汇报时,一张三维全景比平面图更容易达成共识;
- 记录完整性:现场记录的建筑要素(墙、门窗、柱、梁、吊顶、地板)与设备是否协调,三维能快速暴露明显的不合理。
DCDesigner 的 3D 视图就是为这些问题准备的:点击视图区右上角2D/3D 切换按钮(键盘数字键3进入 3D、2返回 2D,Numpad 同样有效)即可由当前平面布局实时生成三维场景。
二、3D 的定位:只读查看器,这是刻意的选择
进入 3D 后:
- 左侧工具条、属性面板与向导自动隐藏,腾出视图空间;顶栏编辑按钮置灰,编辑快捷键同步禁用;
- 3D 为纯查看模式,不可编辑;
- 数据变更(例如在 2D 撤销操作、AI 建模重建场景、隔离隐藏)会实时同步重建三维场景;
- 返回 2D 后各面板恢复原状。
把 3D 做成只读,换来了两件事:
- 数据只有一份:三维模型不是另一个需要维护的副本,而是同一份
objects的另一种表达。改 2D 即刻反映到 3D,不存在「三维模型与图不一致」; - 规则集中:推挤、编号、通道联动等工程规则只需在 2D 编辑路径上实现一次,3D 只负责渲染与查看语义(悬停、隔离、标注)。
3D 场景涵盖的主要构件(全部由 2D 数据程序化生成,无外部模型资源):
类别3D 表达建筑静电地板系统(600×600 HPL 地板砖、架空层裙边与结构楼板)、吊顶(600×600 明架矿棉板,范围铺满机房,边缘收进 60mm)、墙体(按材质:砖墙=彩钢板、混凝土、轻钢龙骨、玻璃隔断)、钢质防火门、铝框玻璃窗、百叶格栅风口、混凝土柱与框架梁设备服务器机柜(钣金柜体、U 位立柱、前后网孔门、柜内设备状态灯、竖拉手、调节支脚)、列头柜、UPS、蓄电池(三层托板 + 电池单元 + 极柱)、灭火器(瓶体/阀座/压把/喷管)、精密空调(双风机圆罩/检修门/显示屏)、地板出风口(格栅/孔板)桥架镀锌钢丝网侧壁 + 网板底(真实镂空透视)、上下边丝、按吊顶面高或结构层高的吊杆、强电红/弱电蓝/光纤绿色带标识通道冷/热通道地面色带 + 彩色边线;封闭通道加柜顶封板、两端端门/封板、铝型材结构框架(角柱/顶梁/门楣/中梃/地轨/拉手)
轴网标注、灯具等不在建模范围内(照明由半球环境光 + 平行主光承担,不建灯具模型)——3D 的职责是校核空间关系与汇报,不是做效果图级别的渲染。
四、为「校核」设计的三个查看工具4.1 悬停尺寸:所见即所量
鼠标移过任意对象即整对象琥珀色提亮(与 2D 选中色同族,光标同步变手型),并浮层显示其名称与真实毫米尺寸:
- 机柜类:宽×深×高;
- 墙:长×厚×高;
- 门窗格栅:宽×高;
- 框架梁:跨长×宽×高 · 梁顶标高;
- 桥架:长×宽×槽高 · 距地;
- 通道:通道宽×通道长(设了通道高则一并显示);
- 吊顶:吊顶面高 · 600×600 网格(仅室内仰视面可拾取,俯视网格线不拦截下方对象)。
移出/拖动视角/滚轮缩放时高亮与浮层即隐;触屏轻点对象显示、点空白隐藏。这条功能让 3D 不只是「看」,而是可以随手复核尺寸。
4.2 右键隔离:把挡视线的对象收起来
右键单击一个对象 → 菜单「隔离(隐藏不显示)」,被隔离的就是这一个对象:
- 它的三维模型整组不显示,也不再参与悬停拾取(不会出现「看不见却能悬停弹尺寸」的幽灵提示);
- 可继续右键其他对象追加隔离,已隔离的继续保持隐藏;
- 退出方式:右键任意位置 →「取消隔离 ▸ 对象名」(逐个恢复)或「退出隔离 / 退出全部隔离」;Esc 退出全部隔离;
- 隔离只改渲染、不改数据:撤销 / AI 建模重建场景后按对象 id 自动重新套用(对象被删则自动剔除并提示,全没了则自动退出),退出 3D 一律还原。
高墙、封闭通道、桥架、整排机柜不再遮挡视线——这是 3D 校核中最实用的一类操作。
4.3 机柜编号浮标:一眼看清哪台是哪台
每台机柜的编号(机柜属性里的名称/编号)以浮标形式浮在柜顶上方:白字深色底板 + 向下小三角指向柜顶。右上角「编号」按钮或 3D 内L键开关,偏好记在本机浏览器。
缩小视图不会堆成一团——三层规则:
- 过远不标:机柜屏幕观感宽度不足18px时不标编号(这时编号比柜子还宽、无从对应),全部隐去时状态栏提示一次,放大后自动重现;
- 够大但挤住时按「近处优先」在屏幕空间贪心占位,重叠的暂时隐去(地标式标注去重叠),放大后全部重现;
- 悬停的那台机柜永远保留(浮标转为琥珀色高亮,与对象提亮同步)。
被隔离的机柜浮标同步消失;整机全景导出会把浮标一并画进图(按世界尺寸换算的矢量文字,8192px 下依然锐利,并遵循同一套去重叠规则)。实现上浮标是DOM 覆盖层:零 draw call、零显存,容器pointer-events:none不挡旋转/平移/悬停拾取,只在真正出帧时更新transform。
五、两种显示风格:实景与素模(BIM)
3D 视图右上角设有风格按钮(仅 3D 中显示,3D 内按T等效切换),偏好持久化:
- 实景(默认):程序化实景材质 + 深色底 + 强主光 + ACES 色调映射——工勘记录「所见即现场」;
- 素模(BIM):浅色低饱和素模材质(按专业族分色:结构灰白 / 配电暖金 / 暖通冷蓝 / 消防低饱和红)、去掉金属高光与实景纹理、构件加轮廓线(盒体棱线随建模一起产出、在对象组内并入静态几何合并,每个对象组至多 1 条,且禁用射线不参与拾取)、浅灰白底 + 柔和均匀光照——BIM 图纸式的方案汇报观感。
切换只换材质与光照:几何由同一份数据派生,不动数据、不动 2D、3D 仍是纯查看,且保持当前视角(不把镜头拉回默认取景)。整机全景导出跟随当前风格。
六、全景导出:把 3D 变成交付材料
3D 状态下点顶栏「导出」→「PNG 图片」,导出的是整机全景图:
- 取景角度跟随使用者当前旋转到的视角,透视相机与屏幕同一投影方式、同一 45° 垂直视场角;
- 按模型包围盒自动取景、全模型完整入画(未旋转时即默认的东南上方约 49° 俯视);
- 白底、去雾、8192px 基准长边(按取景长宽比自适应);
- 瓦片分块渲染:单瓦片 ≤4096px,投影矩阵 NDC 缩放 + 平移精确无缝拼接,低端显卡也可用;
- 程序化纹理同步4× 密度重制,全景期间阴影贴图临时提升至最高 8192避免发糊发块;
- 左下角带比例尺(透视视图按机房中心深度标定,带 ≈ 标记),右下角自动带机房名 / 勘测人 / 日期落款(样式与 2D 导出一致,白晕保证深色场景上可读);
- 导出过程不打扰当前视角,渲染完临时渲染器即销毁。
3D 引擎为 three.js r185 的WebGPURenderer,同一套代码支持双后端:
- 支持 WebGPU 的浏览器(Chrome/Edge 113+、Safari 18+ 等)走 WebGPU;
- 不支持的浏览器(无
navigator.gpu或取不到适配器)自动回退 WebGL 2,无需用户选择; - 进入 3D 时状态栏提示实际生效的后端;排障开关
?renderer=webgl?renderer=webgpu可强制指定。
两种后端画面观感一致(同一 ACES 色调映射 / sRGB 输出 / PCF 软阴影),悬停拾取、右键隔离、全景导出在两种后端下均可用。
7.2 静止不出帧与阴影按需重算
3D 循环常驻 rAF,但只有满足以下之一才真正向 GPU 提交绘制:相机还有阻尼余量、悬停拾取有待办、场景变更(数据重建/隔离/导出后复元)或画布尺寸变化。静止时整帧不提交。
主光方位跟随观察视角(保证任何旋转角度机柜正面受光、阴影落在远离观察者一侧),但设置了1° 死区:方位变化小于 1° 不动光源、也不重算阴影贴图;光源真移动、场景重建、隔离隐藏/还原时才置一次阴影更新。
7.3 静态几何合并与投影件精简
机柜这类对象由很多小零件拼成(侧板/立柱/前后网孔门梁/拉手/支脚/灯板…),30 台机柜就有 600+ 个 Mesh,主 pass 与阴影 pass 各提交一遍。优化两手:
- 静态几何合并:把每个对象组内「同材质 + 同阴影标记」的 Mesh 合并成一个(矩阵烘焙进几何),合并止步于
userData.pick对象组边界——所以右键隔离(整组 visible)与悬停高亮(整组换材质)语义完全不变;回归测试用几何等价性断言合并无损(三角形总数/顶点总数严格相等、包围盒一致、射线仍能命中原对象)。 - 投影件精简:机柜四角 U 位立柱与前后网孔门框梁不投影——它们被柜体包着或紧贴柜体前后面,影子本就落在柜体自身影子里,却占去阴影 pass 大半 draw call。
仓库自带 3D 帧率基准脚本(tests/bench-fps3d.cdp.mjs),可在本机复现实测。README 记录的一组参考数据(无头 Chrome · Intel Xe-LPG 核显 · 1440×818 · WebGPU,旋转视角含阴影重算)为:30 台机柜 47.7 → 60+ FPS;压测 90 台机柜(911 Mesh)10.7 → 52.3 FPS,缩放工况 24.6 → 59.4 FPS。不同硬件结果会不同,但「瓶颈在 draw call 而非填充率」的结论可由--dpr=2对照验证。
八、边界
- 3D 是只读校核与汇报视图,不提供三维编辑;
- 不建模灯具、管线支吊架细节、消防喷淋等专业系统,目标是「空间关系可读」,不是竣工级 BIM 模型;
- 帧率数据依赖硬件与驱动,仓库提供基准脚本而非承诺固定数值;
- 大机房(数百台设备)在低端集显上仍需在「坐标浮标」「阴影」等特性间做取舍(编号可关、
?renderer=webgl可对照排查)。
附:事实来源与核验方式
- 3D 总览与风格:
README.md「3D 机房预览」;实现见public/js/3d/viewer3d.jstheme3d.jsmaterials3d.jsbuilders3d.js - 合并与投影件精简:
public/js/3d/merge3d.js;回归node tests/merge3d.cdp.mjs - 编号浮标:
public/js/3d/labels3d.js;回归node tests/labels3d.cdp.mjs - 右键隔离:
public/js/3d/isolate3d.js;回归node tests/isolate3d.cdp.mjs - 渲染后端:
public/js/3d/renderer3d.js;回归node tests/webgpu3d.cdp.mjs - 像素与帧率基准:
node tests/bench-fps3d.cdp.mjs(支持--renderer--dpr--cabs--style--nolabels等参数)
node tests/merge3d.cdp.mjsnode tests/labels3d.cdp.mjsnode tests/isolate3d.cdp.mjsnode tests/webgpu3d.cdp.mjsnode tests/bench-fps3d.cdp.mjs --cabs=90
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.