Vue3 + Three.js 达成 3D 汽车个性化定制及展示


前言

在现代web开发中,3D可视化技术正变得越来越流行,特别是在汽车、房地产等行业。本文将详细介绍如何使用Vue 3和Three.js构建一个交互式3D汽车展示系统,实现汽车模型的360°旋转查看、部位选择、颜色定制和材质切换等功能。


一、项目概述

这是一个基于Vue 3 Composition API 和 Three.js 开发的3D汽车展示与个性化定制应用,用户可以通过直观的界面浏览3D汽车模型,并对汽车的不同部位进行颜色和材质的个性化定制。

主要功能包括:

  • 3D汽车模型的加载与展示
  • 模型的360°旋转、缩放和视角调整
  • 汽车不同部位的选择(车身、前脸、引擎盖、轮毂、玻璃等)
  • 多种颜色选择定制
  • 多种贴膜材质效果切换

二、技术栈

前端框架:Vue 3 (Composition API)
3D渲染引擎:Three.js
构建工具:Vite
模型加载:GLTFLoader + DRACOLoader
交互控制:OrbitControls

三、核心功能实现

1.Three.js 基础环境搭建

首先,我们需要在Vue组件中搭建Three.js的基础环境,包括场景、相机、渲染器等核心元素。

<script setup>
  import * as THREE from "three";
  import { onMounted, ref } from "vue";
  import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
  let canvasDom = ref(null);
  // 创建场景
  const scene = new THREE.Scene();
  // 创建相机
  const camera = new THREE.PerspectiveCamera(
  75,
  window.innerWidth / window.innerHeight,
  0.1,
  1000
  );
  camera.position.set(0, 2, 6);
  // 创建渲染器
  const renderer = new THREE.WebGLRenderer({
  // 抗锯齿
  antialias: true,
  });
  renderer.setSize(window.innerWidth, window.innerHeight);
  // 渲染循环
  const render = () => {
  renderer.render(scene, camera);
  controls && controls.update();
  requestAnimationFrame(render);
  };
  </script>

2.模型加载与处理

使用GLTFLoader和DRACOLoader加载3D模型,并对模型的不同部位进行识别和处理,为后续的个性化定制做准备。

import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";
import { DRACOLoader } from "three/examples/jsm/loaders/DRACOLoader";
// 汽车部位存储
let carParts = {
body: null,
front: null,
hood: null,
glass: null,
wheels: []
};
onMounted(() => {
// 把渲染器插入到dom中
canvasDom.value.appendChild(renderer.domElement);
// 初始化渲染器,渲染背景
scene.background = new THREE.Color("#1a1a2e");
render();
// 添加控制器
const controls = new OrbitControls(camera, renderer.domElement);
controls.update();
// 添加gltf汽车模型
const loader = new GLTFLoader();
const dracoLoader = new DRACOLoader();
dracoLoader.setDecoderPath("./draco/gltf/");
loader.setDRACOLoader(dracoLoader);
loader.load("./model/bmw01.glb", (gltf) => {
const bmw = gltf.scene;
// 遍历模型,识别不同部位
bmw.traverse((child) => {
if (child.isMesh) {
// 判断是否是轮毂
if (child.name.includes("轮毂")) {
child.material = partMaterials.wheels;
carParts.wheels.push(child);
}
// 判断是否是车身
if (child.name.includes("Mesh002")) {
carParts.body = child;
carParts.body.material = partMaterials.body;
}
// 其他部位识别类似...
}
});
scene.add(bmw);
});
// 窗口大小改变时更新渲染器
window.addEventListener('resize', () => {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
});
});

3.材质系统实现

为汽车的不同部位创建物理材质,并设置颜色和材质的状态管理。

// 颜色列表
const colorList = [
{ name: "红色", value: 0xff0000 },
{ name: "蓝色", value: 0x0000ff },
{ name: "绿色", value: 0x00ff00 },
{ name: "灰色", value: 0x808080 },
{ name: "橙色", value: 0xffa500 },
{ name: "紫色", value: 0x800080 },
{ name: "黑色", value: 0x000000 },
{ name: "白色", value: 0xffffff }
];
// 材质列表
const materialList = [
{ name: "磨砂", clearcoat: 0.3, roughness: 0.8, clearcoatRoughness: 0.9 },
{ name: "金属", clearcoat: 1, roughness: 0.4, clearcoatRoughness: 0.1 },
{ name: "哑光", clearcoat: 0, roughness: 0.7, clearcoatRoughness: 0.2 },
{ name: "镜面", clearcoat: 1, roughness: 0.1, clearcoatRoughness: 0 }
];
// 汽车各部位材质
let partMaterials = {
body: new THREE.MeshPhysicalMaterial({
color: 0xff0000,
metalness: 1,
roughness: 0.5,
clearcoat: 1,
clearcoatRoughness: 0,
}),
// 其他部位材质类似...
};
// 当前选中的部位和材质
let selectedPart = ref('all');
let selectedMaterial = ref(1);

4.交互控制实现

实现颜色选择、材质选择和部位选择的交互逻辑。

// 选择颜色
let selectColor = (colorIndex) => {
const color = colorList[colorIndex].value;
if (selectedPart.value === 'all' || selectedPart.value === 'body') {
partMaterials.body.color.set(color);
}
if (selectedPart.value === 'all' || selectedPart.value === 'front') {
partMaterials.front.color.set(color);
}
// 其他部位颜色设置类似...
};
// 选择材质
let selectMaterial = (materialIndex) => {
selectedMaterial.value = materialIndex;
const material = materialList[materialIndex];
if (selectedPart.value === 'all' || selectedPart.value === 'body') {
partMaterials.body.clearcoat = material.clearcoat;
partMaterials.body.roughness = material.roughness;
partMaterials.body.clearcoatRoughness = material.clearcoatRoughness;
}
// 其他部位材质设置类似...
};
// 选择汽车部位
let selectPart = (part) => {
selectedPart.value = part;
};

5.光照系统设置

设置合理的光照系统,提升3D模型的视觉效果。

// 添加灯光
const ambientLight = new THREE.AmbientLight(0xffffff, 0.6);
scene.add(ambientLight);
const light1 = new THREE.DirectionalLight(0xffffff, 1);
light1.position.set(0, 10, 10);
scene.add(light1);
const light2 = new THREE.DirectionalLight(0xffffff, 0.5);
light2.position.set(-10, 10, 0);
scene.add(light2);
const light3 = new THREE.DirectionalLight(0xffffff, 0.3);
light3.position.set(0, -10, 0);
scene.add(light3);
// 添加环境光
const hemisphereLight = new THREE.HemisphereLight(0xffffff, 0x888888, 0.3);
scene.add(hemisphereLight);

四、模板结构与样式

<template>
    <div class="home">
    <div
      class="canvas-container"
      ref="canvasDom"
  ></div>
    <div class="home-content">
      <div class="home-content-title">
    <h1>3D汽车展示与个性化定制</h1>
    </div>
    <!-- 部位选择 -->
    <h2>选择汽车部位</h2>
        <div class="select">
        <div
          class="select-item part-item"
          v-for="(part, index) in [{ name: '全部', value: 'all' }, /* 其他部位 */]"
          :key="index"
          @click="selectPart(part.value)"
          :class="{ active: selectedPart === part.value }"
        >
      <div class="select-item-text">{{ part.name }}</div>
      </div>
    </div>
    <!-- 颜色选择和材质选择类似 -->
    </div>
  </div>
</template>
<style>
  * {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  }
  .canvas-container {
  width: 100vw;
  height: 100vh;
  overflow: hidden;
  }
  .home-content {
  position: fixed;
  top: 20px;
  right: 20px;
  background: rgba(255, 255, 255, 0.9);
  backdrop-filter: blur(10px);
  padding: 20px;
  border-radius: 15px;
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
  max-width: 300px;
  z-index: 1000;
  }
  /* 响应式设计 */
  @media (max-width: 768px) {
  .home-content {
  position: fixed;
  top: auto;
  bottom: 0;
  right: 0;
  left: 0;
  max-width: none;
  border-radius: 15px 15px 0 0;
  }
  }
</style>

总结

通过本项目,我们成功实现了一个基于Vue 3和Three.js的3D汽车展示与个性化定制系统。这个系统不仅可以展示3D汽车模型,还提供了丰富的交互功能,让用户可以实时定制汽车的外观。

未来可以考虑添加以下功能:

  • 更多汽车模型的支持
  • 内饰定制功能
  • 汽车配置保存和分享功能
  • AR/VR展示模式
  • 更多高级材质和纹理效果

这个项目展示了如何在Web应用中集成3D技术,为用户提供更直观、更沉浸的交互体验,通过学习和实践这个项目,开发者可以掌握Vue 3和Three.js的核心概念和技术,为开发更复杂的3D Web应用打下基础。

附gitee项目地址:https://gitee.com/leaving-dust/3d-car-selection

posted @ 2025-10-20 10:09  yjbjingcha  阅读(2)  评论(0)    收藏  举报