效果展示

代码展示
1.html
<template>
<div>
<div class="title">工厂3D可视化系统</div>
<div class="import_model"></div>
</div>
</template>
2.js 常见搭建以及效果的实现
<script setup>
import { reactive, ref, nextTick, onMounted, watch, onUnmounted } from "vue";
import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";
import { OBJLoader } from "three/examples/jsm/loaders/OBJLoader";
import TWEEN from "@/common/js/libs/Tween.min.js";
import { GUI } from "three/examples/jsm/libs/lil-gui.module.min.js";
let scene, mesh, camera, renderer, axesHelper, grid, controls;
var width = window.innerWidth;
var height = window.innerHeight;
const publicPath = process.env.BASE_URL;
let clock = new THREE.Clock();
let gui = new GUI();
let guiCtrl = {};
let weatherFolder;
let rainy_sw = 1;
let weather = ["rainy", "snowy", "sunny", "cloudy"];
let flow_sw = true;
let group,
speed = 0.5,
isFire = false,
fireColor = "#eb402d";
let urls, urls1;
let krq = new THREE.Object3D();
let textureLoader = new THREE.TextureLoader();
onMounted(() => {
init();
});
</script>
2.1 初始化
function init() {
createScene();
createLight();
createCamera(width, height);
createBackground();
createRender();
createControls();
createAxesHelper();
createPlaneGeometryBasicMaterial();
createBoxGeometryBasicMaterial();
creatRoadSurface();
createRoundGeometryBasicMaterialMax();
createRoundGeometryBasicMaterialMin();
crateWall();
initDataGUI();
if (rainy_sw < 3) {
createPointRainy();
}
render();
}
创建场景
function createScene() {
scene = new THREE.Scene();
}
创建光源
function createLight() {
var point = new THREE.PointLight(0xffffff);
point.position.set(400, 200, 300);
scene.add(point);
var ambient = new THREE.AmbientLight("#ffffff", 1);
scene.add(ambient);
}
创建相机
function createCamera(width, height) {
var k = width / height;
var s = 200;
camera = new THREE.PerspectiveCamera(
45,
window.innerWidth / window.innerHeight,
0.1,
20000
);
camera.position.set(200, 300, 200);
camera.lookAt(scene.position);
}
设置背景
function createBackground() {
urls = [
"model/textures/posx.jpg",
"model/textures/negx.jpg",
"model/textures/posy.jpg",
"model/textures/negy.jpg",
"model/textures/posz.jpg",
"model/textures/negz.jpg",
];
urls1 = [
"model/textures/posx_gray.jpg",
"model/textures/negx_gray.jpg",
"model/textures/posy_gray.jpg",
"model/textures/negy_gray.jpg",
"model/textures/posz_gray.jpg",
"model/textures/negz_gray.jpg",
];
let url = rainy_sw == 3 ? urls : urls1;
scene.background = new THREE.CubeTextureLoader().load(url);
}
创建渲染器
function createRender() {
renderer = new THREE.WebGLRenderer();
renderer.setSize(width, height);
renderer.outputEncoding = THREE.sRGBEncoding;
renderer.shadowMap.enabled = true;
nextTick(() => {
document.querySelector(".import_model").appendChild(renderer.domElement);
});
}
创建控制器
function createControls() {
controls = new OrbitControls(camera, renderer.domElement);
controls.addEventListener("change", () => {
renderer.render(scene, camera);
});
}
function createAxesHelper() {
axesHelper = new THREE.AxesHelper(250);
scene.add(axesHelper);
}
function createPlaneGeometryBasicMaterial() {
var material = new THREE.MeshBasicMaterial({
map: textureLoader.load("/model/textures/floor3.png"),
transparent: true,
side: THREE.DoubleSide,
});
var geometry = new THREE.PlaneGeometry(270, 260);
var plane = new THREE.Mesh(geometry, material);
plane.rotation.x = -0.5 * Math.PI;
plane.position.y = -0.1;
scene.add(plane);
}
辅助坐标系
function createAxesHelper() {
axesHelper = new THREE.AxesHelper(250);
scene.add(axesHelper);
}
将平面添加到场景中
function createPlaneGeometryBasicMaterial() {
var material = new THREE.MeshBasicMaterial({
map: textureLoader.load("/model/textures/floor3.png"),
transparent: true,
side: THREE.DoubleSide,
});
var geometry = new THREE.PlaneGeometry(270, 260);
var plane = new THREE.Mesh(geometry, material);
plane.rotation.x = -0.5 * Math.PI;
plane.position.y = -0.1;
scene.add(plane);
}

创建并复制房屋
function createBoxGeometryBasicMaterial() {
const loader = new OBJLoader();
loader.load(`/model/textures/003.obj`, function (obj) {
var mesh = obj.children[0];
mesh.material = new THREE.MeshBasicMaterial({
map: textureLoader.load("/model/textures/003.png"),
});
mesh.scale.set(1.3, 1.4, 1.5);
mesh.position.set(11, 0, -85);
scene.add(mesh);
for (let i = 0; i < 2; i++) {
for (let j = 0; j < 3; j++) {
var mc = mesh.clone();
scene.add(mc);
mc.translateX(i * 52);
mc.translateZ(j * 83);
}
}
});
}

添加侧边的路
function creatRoadSurface() {
var geometry = new THREE.PlaneGeometry(24, 280);
var texture = textureLoader.load("/model/textures/road2.png");
var material = new THREE.MeshBasicMaterial({
map: texture,
side: THREE.DoubleSide,
});
texture.wrapS = THREE.RepeatWrapping;
texture.wrapT = THREE.RepeatWrapping;
texture.repeat.set(1, 10);
var mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
mesh.rotateX(-Math.PI / 2);
mesh.position.x = 100.5;
}

创建圆仓大
function createRoundGeometryBasicMaterialMax() {
const loader = new OBJLoader();
loader.load(`/model/textures/gong001.obj`, function (obj) {
var mesh = obj.children[0];
mesh.material = new THREE.MeshBasicMaterial({
map: textureLoader.load("/model/textures/d001.png"),
transparent: true,
side: THREE.DoubleSide,
clipIntersection: true,
});
mesh.rotateZ(Math.PI);
mesh.position.set(-40, 36, -105);
scene.add(mesh);
for (let i = 0; i < 2; i++) {
for (let j = 0; j < 3; j++) {
var mc = mesh.clone();
scene.add(mc);
mc.translateX(i * 28);
mc.translateZ(j * 20);
}
}
});
}

创建圆仓小
function createRoundGeometryBasicMaterialMin() {
const loader = new OBJLoader();
loader.load(`/model/textures/002.obj`, function (obj) {
var mesh = obj.children[0];
mesh.material = new THREE.MeshBasicMaterial({
map: new THREE.TextureLoader().load("/model/textures/002.png"),
transparent: true,
side: THREE.DoubleSide,
clipIntersection: true,
});
mesh.rotateZ(Math.PI);
mesh.position.set(-40, 20, -19);
for (let i = 0; i < 2; i++) {
for (let j = 0; j < 6; j++) {
var mc = mesh.clone();
mc.translateX(i * 28);
mc.translateZ(j * 24);
scene.add(mc);
}
}
});
}

创建围栏
function crateWall() {
const loader = new OBJLoader();
loader.load(`/model/textures/wall.obj`, function (obj) {
obj.scale.set(0.98, 0.6, 1);
var texLan = textureLoader.load("/model/textures/lan2.png");
texLan.wrapS = THREE.RepeatWrapping;
texLan.wrapT = THREE.RepeatWrapping;
obj.children[0].material = new THREE.MeshBasicMaterial({
map: texLan,
side: THREE.DoubleSide,
transparent: true,
});
obj.children[1].material = new THREE.MeshBasicMaterial({
map: new THREE.TextureLoader().load("/model/textures/door.png"),
side: THREE.DoubleSide,
transparent: true,
});
scene.add(obj);
});

创建GUI
function initDataGUI() {
weatherFolder = gui.addFolder("Weather");
guiCtrl.speed = speed;
gui.add(guiCtrl, "speed", 0, 10).onChange((e) => {
speed = e;
});
guiCtrl.backgroundColor = fireColor;
gui.addColor(guiCtrl, "backgroundColor").onChange((e) => {
console.log(e);
fireColor = e;
});
guiCtrl.isFire = isFire;
gui.add(guiCtrl, "isFire").onChange((e) => {
addFire();
group.traverse(function(obj) {
console.log(obj.name)
})
isFire = e;
});
guiCtrl.weather = weather[rainy_sw - 1];
gui.add(guiCtrl, "weather", weather).onChange((e) => {
let indexNum = weather.indexOf(e);
rainy_sw = indexNum + 1;
scene.remove(scene.getObjectByName("particles_rainy"));
scene.remove(scene.getObjectByName("particles_snowy"));
let url = rainy_sw == 3 ? urls : urls1;
scene.background = new THREE.CubeTextureLoader().load(url);
if (rainy_sw < 3) {
createPointRainy();
}
});
guiCtrl.name = "工厂3D可视化系统";
gui.add(guiCtrl, "name").onChange((e) => {
console.log(e);
});
guiCtrl.weather2 = weather3;
guiCtrl.weather3 = weather4;
weatherFolder.add(guiCtrl, "weather2").onChange((e) => {
console.log(e);
});
weatherFolder.add(guiCtrl, "weather3").onChange((e) => {
console.log(e);
});
weatherFolder.open();
}

添加天气
function createPointRainy() {
var img =
rainy_sw == 1 ? "raindrop.png" : rainy_sw == 2 ? "snowflake.png" : "";
var name =
rainy_sw == 1 ? "particles_rainy" : rainy_sw == 2 ? "particles_snowy" : "";
let num = 400;
var texture = new THREE.TextureLoader().load("model/textures/" + img);
group = new THREE.Group();
for (let i = 0; i < num; i++) {
var spriteMaterial = new THREE.SpriteMaterial({
color: 0xffffff,
map: texture,
transparent: true,
opacity: 1,
blending: THREE.AdditiveBlending,
sizeAttenuation: true,
});
var sprite = new THREE.Sprite(spriteMaterial);
group.add(sprite);
sprite.scale.set(4, 5, 1);
var k1 = Math.random() - 0.5;
var k2 = Math.random() - 0.5;
sprite.position.set(1000 * k1, 300 * Math.random(), 1000 * k2);
group.name = name;
scene.add(group);
}
}
设计雨滴速度
function rainAnimate() {
group.children.forEach((sprite) => {
sprite.position.y -= speed;
if (sprite.position.y < 0) {
sprite.position.y = 200;
}
});
}
开火
function addFire() {
var texture = new THREE.TextureLoader().load("model/textures/flamex.png");
var material = new THREE.SpriteMaterial({
map: texture,
color: fireColor,
blending: THREE.AdditiveBlending,
});
for (var i = 0; i < 2000; i++) {
var particle = new THREE.Sprite(material);
initParticle(particle, i);
group.name = "particles_flame";
scene.add(particle);
}
}
粒子加载
function initParticle(particle, delay) {
particle.position.set(0, Math.random() + 20, 0);
particle.scale.x = particle.scale.y = Math.random() * 13;
var xx = Math.random() * 40 - 20;
var yy = Math.cos((Math.PI / 100) * xx) * 80;
new TWEEN.Tween(particle.position)
.delay(delay)
.to(
{
x: xx,
y: yy,
z: Math.random() * 40 - 20,
},
2000
)
.onComplete(function () {
initParticle(particle, delay);
})
.start();
new TWEEN.Tween(particle.scale)
.delay(delay)
.to(
{
x: 0.01,
y: 0.01,
},
1000
)
.start();
}