<template>
<div class="home">
<div class="canvas-container" ref="canvasDom"></div>
<div class="choose">
<div>车身颜色选择:</div>
<div class="choose-list">
<div
class="item"
v-for="item in colorList"
:key="item"
:style="{ background: item }"
@click="setCarColor(item)"></div>
</div>
</div>
<div class="zy">
<div>座椅颜色:</div>
<div class="zy-list">
<div
class="zy-item"
v-for="item in zyList"
:key="item"
:style="{ background: item }"
@click="setCarZy(item)"></div>
</div>
</div>
</div>
</template>
<script setup>
import * as THREE from "three"
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls"
import {onMounted,ref} from 'vue'
import {GLTFLoader} from "three/examples/jsm/loaders/GLTFLoader"
import {DRACOLoader} from "three/examples/jsm/loaders/DRACOLoader"
let controls,gridHelper
let canvasDom = ref(null)
let fll
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 = ()=>{
// 车轮模拟滚动
const time = - performance.now() / 1000;
for ( let i = 0; i < arr.length; i ++ ) {
arr[ i ].rotation.x = time * Math.PI * 2;
}
// 网格移动 与 车轮模拟滚动 ,从而制造车子向前移动的效果
gridHelper.position.z = ( time ) % 1
renderer.render(scene, camera)
controls && controls.update()
requestAnimationFrame(render)
}
/*****
* wheel 轮毂 leather 座椅 interior_light 、
* grills内饰 glass 挡风玻璃 chrome 车标/后视镜 carpet 脚垫 bre_trim控制器
* brakes 尾灯 body 车衣 tire车胎 , carGlass,carLeather ,
* **/
let arr =[]
let carBody , carTire,carWheel,carGlass,carChrome
const carBodyMat = new THREE.MeshPhysicalMaterial({
color:0xff0000,
metalness:1,
roughness:0.5,
clearcoat:1,
clearcoatRoughness:0
})
const carTireMat = new THREE.MeshPhysicalMaterial({
color:0x000000,
metalness:1,
roughness:0.5,
// transimission:1
})
const carOtherMat = new THREE.MeshPhysicalMaterial({
color:0x000000,
metalness:1,
roughness:0.5,
})
const carGlassMat = new THREE.MeshPhysicalMaterial({
color:0xffffff,
metalness:0,
roughness:0,
transmission:1,
transparent:true
})
const carChromeMat = new THREE.MeshPhysicalMaterial({
color:0xffee,
metalness:0,
roughness:0,
transmission:1,
transparent:true
})
let colorList = [
"green","gray","orange","purple"
]
let zyList = ["black","darkred"]
let setCarColor =(e)=>{
carBodyMat.color.set(e)
}
const setCarZy = (e)=>{
carOtherMat.color.set(e)
}
onMounted(()=>{
canvasDom.value.appendChild(renderer.domElement)
renderer.setClearColor('#000')
scene.background = new THREE.Color('#ccc')
scene.environment = new THREE.Color('#ccc')
// 添加网格
gridHelper = new THREE.GridHelper(20,20)
gridHelper.material.opacity = 0.2
gridHelper.material.transparent = true
scene.add(gridHelper)
controls = new OrbitControls(camera,renderer.domElement)
controls.update()
// 添加汽车模型
const loader = new GLTFLoader()
const dracoLoader = new DRACOLoader()
dracoLoader.setDecoderPath('./draco/gltf/')
loader.setDRACOLoader(dracoLoader)
loader.load('./model/ferrari.glb',(glft)=>{
fll = glft.scene
fll.rotation.y = Math.PI-12
fll.traverse(child=>{
if (child.isMesh) {
console.log(child.name);
}
// wheel 轮毂 leather 座椅 interior_light 、grills内饰 glass 挡风玻璃 chrome 车标/后视镜 carpet 脚垫 bre_trim控制器
// brakes 尾灯 body 车衣 tire车胎
// child.name.includes('trim')
if (child.isMesh && child.name.includes('body') ) { // body
carBody = child
carBody.material = carBodyMat
}
if (child.isMesh && child.name.includes('tire')) {
carTire = child
carTire.material = carTireMat
arr.push(child)
}
if (child.isMesh && child.name.includes('wheel')) {
carWheel = child
carWheel.material = carTireMat
arr.push(child)
}
if (child.isMesh && child.name.includes('glass') || child.name.includes("brakes") || child.name.includes('bre_trim')) {
child.material = carGlassMat
carGlass = child
carGlass.material = carGlassMat
}
if (child.isMesh && child.name.includes('chrome')) {
carChrome = child
carChrome.material = carChromeMat
}
if (child.isMesh && child.name.includes('leather') || child.name.includes('interior_light')||child.name.includes('lights_red') || child.name.includes('grills') || child.name.includes('carpet') || child.name.includes('bre_trim')) {
child.material = carOtherMat
}
})
scene.add(fll)
})
// 添加灯光
const light1= new THREE.DirectionalLight(0xffffff,1)
light1.position.set(0 ,0,10)
scene.add(light1)
const light2= new THREE.DirectionalLight(0xffffff,1)
light2.position.set(0 ,0,-10)
scene.add(light2)
const light3= new THREE.DirectionalLight(0xffffff,1)
light3.position.set(10 ,0,0)
scene.add(light3)
const light4= new THREE.DirectionalLight(0xffffff,1)
light4.position.set(-10 ,0,0)
scene.add(light4)
const light5= new THREE.DirectionalLight(0xffffff,1)
light5.position.set(0 ,10,0)
scene.add(light5)
render()
})
</script>
<style scoped>
.choose {
color: black;
position: absolute;
top: 20px;
width: 200px;
left: 20px;
font-size: 18px;
font-weight: 600;
}
.choose-list {
display: flex;
justify-content: space-evenly;
margin-left: 60px;
margin-top: 10px;
}
.item {
width: 30px;
height: 30px;
margin-left: 5px;
border-radius: 5px;
}
.zy {
color: black;
position: absolute;
top: 100px;
width: 200px;
left: 20px;
font-size: 18px;
font-weight: 600;
}
.zy-list {
display: flex;
justify-content: space-evenly;
margin-left: 60px;
margin-top: 10px;
}
.zy-item {
width: 30px;
height: 30px;
margin-left: 5px;
border-radius: 5px;
}
</style>
汽车3D模型:
http://链接:https://pan.baidu.com/s/1is6SDkQ29OHgVGmHYBz2BA