工厂能源 3D 场景 · 源码解读笔记
本页对 factory-3d.html 进行结构化拆解。 该文件以 Three.js 为核心,构建了一个包含工厂主体、光伏阵列、储能电池柜、充电桩、冷却塔、风力发电机、变压器与控制中心的可交互能源沙盘。 所有几何体、贴图、流光均由代码实时生成,无任何外部资源依赖。
归档概览
一篇发布在「个人开发日志」上的源码解析笔记,记录对一个工业元宇宙演示场景的结构化拆解。
Three.js 实时渲染
基于 PerspectiveCamera + OrbitControls 实现轨道交互;通过 requestAnimationFrame 与 THREE.Clock 驱动统一动画时钟。
- scene场景树与多光源
- rendererWebGL 抗锯齿输出
- controls阻尼轨道控制
程序化几何体
厂房、烟囱、电池柜、风机、冷却塔等所有模型均通过 BoxGeometry、CylinderGeometry、PlaneGeometry 等基础图元组合生成。
- CanvasTexture代码贴图
- RingGeometry扫描光圈
- LineSegments网格边界
动画与流场
电力输送以 CatmullRomCurve3 路径粒子流呈现;电池柜 LED 呼吸、信号塔闪烁、风机旋转、冷却塔蒸汽粒子均以 sin/cos 实时驱动。
- flowPoints200 路径流光
- turbines多组叶片旋转
- steam上升衰减
九大功能模块拆解
从 factory-3d.html 中可识别出以下核心模块,每个模块都对应工厂能源链的一个具体环节。
主生产厂房
~L945 · L949-988
厂房外壳为 BoxGeometry,顶部金属屋顶 + 蓝色 LED 灯带;底座铺设混凝土材质,并叠加屋顶通风口与门洞。
光伏阵列
~L746
200 个独立太阳能板单元铺设于屋顶与地面,按规则网格排布;apCount 控制单元数量上限,可被滑杆实时调节。
电池储能柜
~L2112-2120
由多组机柜组成,每柜内置呼吸式 LED 指示灯,颜色随 sin(t) 渐变,模拟 SOC 电量变化。
充电桩集群
~L2092
充电桩负载 EV/P.evMax 实时计算,UI 进度条同步刷新;模拟 V2G 双向能量流。
风力发电机
~L2153-2164
每台风机有 3 片叶片,叶片位置由 cos/sin 计算得到并随时间旋转,呈现真实运动轨迹。
冷却塔与蒸汽
~L2137-2146
冷却塔顶部持续释放半透明粒子蒸汽,随时间上升 + 透明度衰减 + 体积放大,模拟水汽扩散。
主变压器
~L2128-2135
配备两台反向旋转的散热风扇 (fan0/fan1) + 状态指示灯 + 容量进度条,是能源调度的枢纽节点。
控制中心
~L2148-2151
实时刷新的 Canvas 屏幕 (drawScreen) + 闪烁信号塔 + 选中态旋转光环,构成调度指挥入口。
能量流光路径
~L2105-2110
沿 CatmullRomCurve3 曲线分布的粒子在每帧根据 userData.t 增量推进,呈现能源"涌动"效果。
渲染管线与动画循环
从初始化到每帧更新,factory-3d.html 走的是一条典型 Three.js 单文件工程链路。
资源引导
Loader 进度条 + 步骤提示,按需异步加载 Three.js 库。
场景搭建
buildFactory 创建 9 大设备并挂载到 scene。
流光路径
定义曲线 + 粒子池,将能量流对象加入场景。
控制绑定
OrbitControls 启用阻尼 + 滑杆/按钮事件注入。
动画循环
animate() 中更新时钟、动画态与渲染输出。
关键源码摘录
以下片段节选自 factory-3d.html,展示动画主循环与流光推进的核心逻辑。
// ================== ANIMATION ================== const clock = new THREE.Clock(); function animate() { requestAnimationFrame(animate); const t = clock.getElapsedTime(); controls.update(); updateParams(); // 能量流光沿 CatmullRom 曲线推进 for (let i = 0; i < flowPoints.length; i++) { const p = flowPoints[i]; p.userData.t += p.userData.speed * 0.012; if (p.userData.t > 1) p.userData.t -= 1; p.userData.curve.getPointAt(p.userData.t, p.position); } // 电池柜 LED 呼吸 if (devices.battery.userData.cabinets) { const cabs = devices.battery.userData.cabinets; for (let i = 0; i < cabs.length; i++) { if (cabs[i].userData.led) { const v = 0.5 + 0.5 * Math.sin(t * 2.5 + i * 0.5); cabs[i].userData.led.material.color.setRGB(0, v, 0.5); } } } renderer.render(scene, camera); }
运行完整 3D 场景 →
factory-3d.html · OPEN IN NEW TAB