Three.js 工业 3D 可视化:生产线状态监控系统实现方案

在工业数字化转型过程中,3D 可视化监控系统凭借直观、沉浸式的优势,成为车间管理的重要工具。本文将详细介绍如何使用 Three.js 构建一套生产线 3D 状态监控系统,实现设备状态展示、产能数据可视化、交互式操作等核心功能

一、项目背景与技术选型

1. 项目需求

  • 3D 可视化展示生产线布局及设备状态
  • 实时显示生产线运行参数(产能、产量、状态等)
  • 支持多生产线切换查看
  • 设备状态可视化(运行 / 维护 / 停机)
  • 交互式操作(视角旋转)

2. 技术栈选型

  • 3D 核心库:Three.js(Web 端 3D 图形渲染引擎)

  • 辅助库

    • GLTFLoader(3D 模型加载)
    • OrbitControls(相机控制)
    • CSS3DRenderer/CSS2DRenderer(3D/2D 标签渲染)
  • UI 框架:Element UI(进度条、样式组件)

  • 动画库:animate-number(数值动画)

  • 样式预处理:SCSS(样式模块化管理)

二、核心功能实现

1. 3D 场景基础搭建

场景初始化是 Three.js 项目的基础,需要完成场景、相机、渲染器三大核心对象的创建。

javascript 复制代码
init() {
  // 1. 创建场景
  this.scene = new THREE.Scene();

  // 2. 创建网格模型(生产线底座)
  const geometry = new THREE.BoxGeometry(640, 1, 70);
  const material = new THREE.MeshLambertMaterial({
    color: 0xffffff,
    transparent: true,
    opacity: 1
  });
  this.mesh = new THREE.Mesh(geometry, material);
  this.mesh.position.set(0, -140, 0);
  this.scene.add(this.mesh);

  // 3. 光源设置(点光源+环境光)
  const pointLight = new THREE.PointLight(0xffffff, 0.5);
  pointLight.position.set(0, 200, 300);
  this.scene.add(pointLight);
  
  const ambientLight = new THREE.AmbientLight(0xffffff, 0.3);
  this.scene.add(ambientLight);

  // 4. 相机设置(正交相机,适合工业场景展示)
  const container = document.getElementById("container");
  const width = container.clientWidth;
  const height = container.clientHeight;
  const aspectRatio = width / height;
  const scale = 230; // 场景显示范围系数

  this.camera = new THREE.OrthographicCamera(
    -scale * aspectRatio,
    scale * aspectRatio,
    scale,
    -scale,
    1,
    1000
  );
  this.camera.position.set(-100, 100, 500);
  this.camera.lookAt(this.scene.position);

  // 5. 渲染器设置
  this.renderer = new THREE.WebGLRenderer({
    antialias: true, // 抗锯齿
    preserveDrawingBuffer: true // 保留绘制缓存
  });
  this.renderer.setSize(width, height);
  this.renderer.setClearColor(0xffffff, 0); // 透明背景
  container.appendChild(this.renderer.domElement);

  // 6. 控制器设置(支持鼠标交互)
  this.controls = new OrbitControls(this.camera, this.renderer.domElement);
  this.controls.addEventListener("change", () => {
    this.renderer.render(this.scene, this.camera);
  });

  // 初始渲染
  this.renderer.render(this.scene, this.camera);
}

2. 3D 模型加载与生产线构建

(1)外部模型加载

使用 GLTFLoader 加载生产线设备 3D 模型(glb 格式),并设置模型位置:

javascript 复制代码
loadGltf() {
  const loader = new GLTFLoader();
  loader.load("../model/cj.glb", (gltf) => {
    gltf.scene.position.set(16, -139, 140); // 调整模型位置适配场景
    this.scene.add(gltf.scene);
    this.renderer.render(this.scene, this.camera);
  });
}

(2)生产线围墙构建

通过 BufferGeometry 自定义几何体,创建生产线边界围墙,并用纹理贴图美化:

javascript 复制代码
addWall() {
  // 围墙顶点坐标
  const vertices = [-320, 35, 320, 35, 320, -35, -320, -35, -320, 35];
  const geometry = new THREE.BufferGeometry();
  const posArr = [];
  const uvArr = [];
  const height = -40; // 围墙高度

  // 构建围墙三角面
  for (let i = 0; i < vertices.length - 2; i += 2) {
    // 两个三角形组成一个矩形面
    posArr.push(
      vertices[i], vertices[i+1], -140,
      vertices[i+2], vertices[i+3], -140,
      vertices[i+2], vertices[i+3], height,
      vertices[i], vertices[i+1], -140,
      vertices[i+2], vertices[i+3], height,
      vertices[i], vertices[i+1], height
    );
    // UV贴图坐标
    uvArr.push(0,0, 1,0, 1,1, 0,0, 1,1, 0,1);
  }

  // 设置几何体属性
  geometry.attributes.position = new THREE.BufferAttribute(new Float32Array(posArr), 3);
  geometry.attributes.uv = new THREE.BufferAttribute(new Float32Array(uvArr), 2);
  geometry.computeVertexNormals(); // 计算法线

  // 加载纹理并创建材质
  this.texture = new THREE.TextureLoader().load("../images/linearGradient.png");
  this.mesh = new THREE.Mesh(geometry, new THREE.MeshLambertMaterial({
    color: this.dict_color[this.progress.state],
    map: this.texture,
    transparent: true,
    side: THREE.DoubleSide, // 双面渲染
    depthTest: false
  }));
  this.mesh.rotation.x = -Math.PI * 0.5; // 旋转适配场景
  this.scene.add(this.mesh);
}

4. 状态可视化与数据面板

(1)多状态颜色映射

定义生产线三种状态(运行中 / 维护中 / 停机中)的颜色映射,实现状态可视化:

javascript 复制代码
dict_color: {
  运行中: "#32e5ad", // 绿色
  维护中: "#fb8d1c", // 橙色
  停机中: "#e9473a"  // 红色
}

(2)数据面板设计

通过 CSS2DRenderer 将数据面板作为 2D 标签添加到 3D 场景中,实时展示生产线参数:

html 复制代码
<div id="tooltip">
  <div class="title">DIP 2-1涂覆线</div>
  <div class="progress">
    <p class="state">
      <span class="icon" :style="{ backgroundColor: dict_color[progress.state] }"></span>
      {{ progress.state }}
    </p>
    <p class="value">
      <animate-number
        from="0"
        :key="progress.value"
        :to="progress.value"
        duration="2000"
        easing="easeOutQuad"
        :formatter="formatter"
      ></animate-number>
      %
    </p>
    <el-progress :percentage="progress.value" :show-text="false" :color="dict_color[progress.state]"></el-progress>
  </div>
  <ul class="infoList">
    <li v-for="(item, index) in infoList" :key="index">
      <label>{{ item.label }}:</label>
      <span>{{ item.value }}</span>
    </li>
  </ul>
</div>
javascript 复制代码
addTooltip() {
  const tooltipDom = document.getElementById("tooltip");
  const tooltipObject = new CSS2DObject(tooltipDom);
  tooltipObject.position.set(0, 120, 0); // 面板在3D场景中的位置
  this.scene.add(tooltipObject);
  this.labelRenderer2D.render(this.scene, this.camera);
}

5. 多生产线切换功能

支持切换查看多条生产线状态,通过点击标签切换数据和状态颜色:

javascript 复制代码
changeType(index) {
  this.typeIndex = index;
  // 根据索引切换不同生产线的状态数据
  if (index % 3 === 0) {
    this.progress = this.progress1; // 运行中
  } else if (index % 3 === 1) {
    this.progress = this.progress2; // 维护中
  } else {
    this.progress = this.progress3; // 停机中
  }
}

// 监听progress变化,更新3D模型颜色
watch: {
  progress: {
    handler() {
      this.mesh.material.color.set(this.dict_color[this.progress.state]);
      this.renderer.render(this.scene, this.camera);
    },
    deep: true
  }
}

6. 响应式适配

处理窗口大小变化,确保 3D 场景自适应调整:

javascript 复制代码
onWindowResize() {
  const container = document.getElementById("container");
  const width = container.clientWidth;
  const height = container.clientHeight;

  // 更新渲染器尺寸
  this.renderer.setSize(width, height);
  this.labelRenderer.setSize(width, height);
  this.labelRenderer2D.setSize(width, height);

  // 更新相机参数
  const aspectRatio = width / height;
  const scale = 230;
  this.camera.left = -scale * aspectRatio;
  this.camera.right = scale * aspectRatio;
  this.camera.top = scale;
  this.camera.bottom = -scale;
  this.camera.updateProjectionMatrix();

  // 重新渲染
  this.renderer.render(this.scene, this.camera);
}

三、关键技术

1. 3D 与 2D 融合渲染

通过 CSS3DRenderer 和 CSS2DRenderer 实现 3D 场景与 2DUI 的无缝融合:

  • CSS2DRenderer:用于数据面板等需要始终面向相机的 2D 元素
  • CSS3DRenderer:用于生产线节点标签等需要 3D 空间定位的元素

2. 状态可视化设计

  • 颜色编码:用不同颜色区分设备状态,符合工业监控的视觉习惯
  • 动态更新:状态变化时实时更新 3D 模型颜色和数据面板
  • 图标标识:通过图标和文字结合,增强状态辨识度

3. 性能优化

  • 抗锯齿设置:提升 3D 模型显示清晰度
  • 双面渲染:确保围墙等几何体正反面都能正常显示
  • 纹理复用:减少重复纹理加载,提升性能
  • 事件监听优化:仅在必要时重新渲染场景
相关推荐
何贤3 天前
🪐 行星科技概念官网!Hero Section 回归!(Three.js ✨)
前端·javascript·three.js
爱看书的小沐3 天前
【小沐杂货铺】基于Three.js绘制三维管道Pipe(WebGL、vue、react)
javascript·vue.js·webgl·three.js·管道·pipe·三维管道
小码编匠5 天前
Three.js 遇上 Vue3 开发现代化 3D 可视化编辑系统
vue.js·typescript·three.js
阿明Drift7 天前
从炫酷粒子星云学 Three.js:深度解析一个 15 万粒子的 GPU 动画系统
前端·three.js
秋田君10 天前
3D热力图封装组件:Vue + Three.js 实现3D图表详解
javascript·vue.js·3d·three.js·热力图
Mintopia13 天前
🌌 Three.js 几何变化动画配合噪声粒子教程:让你的代码也会“呼吸”
前端·javascript·three.js
爱看书的小沐18 天前
【小沐杂货铺】基于Three.js渲染三维风力发电机(WebGL、vue、react、WindTurbine)
javascript·vue.js·webgl·three.js·opengl·风力发电机·windturbine
Dragonir18 天前
React+Three.js 实现 Apple 2025 热成像 logo
前端·javascript·html·three.js·页面特效