文章目录
前言
在现代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的基础环境,包括场景、相机、渲染器等核心元素。
javascript
<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模型,并对模型的不同部位进行识别和处理,为后续的个性化定制做准备。
javascript
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.材质系统实现
为汽车的不同部位创建物理材质,并设置颜色和材质的状态管理。
javascript
// 颜色列表
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.交互控制实现
实现颜色选择、材质选择和部位选择的交互逻辑。
javascript
// 选择颜色
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模型的视觉效果。
javascript
// 添加灯光
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);
四、模板结构与样式
html
<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应用打下基础。