Threejs Example 10: Car Model Exhibition


<template>
    <div>
        <div class="colors">
           <span @click="selectColor(index)" class="item" 
                v-for="(item,index) in colors" 
                :style="{backgroundColor:item.value}">{
     
     {item.name}}</span>
        </div>
        <div class="material">
           <span @click="selectMeterial(index)" class="material-item" 
                v-for="(item,index) in materials" 
                :style="{backgroundColor:item.value}">{
     
     {item.name}}</span>
        </div>
    </div>
  </template>
  
  <script setup>
  import { ref } from 'vue'
  import * as THREE from "three"
  import {OrbitControls} from "three/examples/jsm/controls/OrbitControls"
  import {GLTFLoader} from "three/examples/jsm/loaders/GLTFLoader"
  import {DRACOLoader} from "three/examples/jsm/loaders/DRACOLoader"

 
  
  const scene=new THREE.Scene()

  //相机
  const camara=new THREE.PerspectiveCamera(75,window.innerWidth/window.innerHeight,0.1,1000)
  camara.position.set(1,4,10)
  
  //平面
  const grid=new THREE.GridHelper(30,30)
  scene.add(grid)
  
  //颜色数据

    const colors=[
        {name:"粉色",value:"#f8c6fd"},
        {name:"亮红",value:"#f00"},
        {name:"天蓝",value:"#84bbeb"},
        {name:"紫色",value:"#ac84eb"},
    ]

    //材质
    const materials=[
        {name:"磨砂",value:1},
        {name:"烤漆",value:0},
    ]

  //几何体
//   const cube=new THREE.Mesh(
//       new THREE.BoxGeometry(2,2,2),
//       new THREE.MeshBasicMaterial({color:"#f90"})
//   )
//   cube.position.set(0,1,0)
//   scene.add(cube)



//创建材质

let bodyMaterial=new THREE.MeshPhysicalMaterial({
    color:"#f00",
    metalness:1,
    roughness:0.5,
    clearcoat:1,
    clearcoatRoughness:0
})
let frontMaterial=new THREE.MeshPhysicalMaterial({
    color:"#f00",
    metalness:1,
    roughness:0.5,
    clearcoat:1,
    clearcoatRoughness:0
})
let hoodMaterial=new THREE.MeshPhysicalMaterial({
    color:"#f00",
    metalness:1,
    roughness:0.5,
    clearcoat:1,
    clearcoatRoughness:0
})
let wheelMaterial=new THREE.MeshPhysicalMaterial({
    color:"#f00",
    metalness:1,
    roughness:0.1,
})

let glassMaterial=new THREE.MeshPhysicalMaterial({
    color:"#fff",
    metalness:0,
    roughness:0.1,
    transmission:1,
    transparent:true
})
//加载模型

const loader=new GLTFLoader()
const dracoLoader=new DRACOLoader()
dracoLoader.setDecoderPath("public/draco/")
loader.setDRACOLoader(dracoLoader)

loader.load("model/bmw01.glb",(texture)=>{
    let bmw=texture.scene
    bmw.traverse((child)=>{

        if(child.isMesh&&child.name.includes("轮毂")){
            wheels.push(child)
            child.material=wheelMaterial
        }
        //车身
        if(child.isMesh&&child.name.includes("Mesh002")){
            carBody=child
            carBody.material=bodyMaterial
        }
        //前脸
        if(child.isMesh&&child.name.includes("前脸")){
            frontCar=child
            frontCar.material=frontMaterial
        }
        //引擎盖1
        if(child.isMesh&&child.name.includes("引擎盖")){
            hoodCar=child
            hoodCar.material=hoodMaterial
        }
        //挡风玻璃
        if(child.isMesh&&child.name.includes("挡风玻璃")){
            glassCar=child;
            glassCar.material= glassMaterial
        }
    })
    scene.add(bmw)

})

  //光源
let light1=new THREE.DirectionalLight("#fff",1)
light1.position.set(0,0,10)
scene.add(light1)
let light2=new THREE.DirectionalLight("#fff",1)
light2.position.set(0,0,-10)
scene.add(light2)
let light3=new THREE.DirectionalLight("#fff",1)
light3.position.set(-10,0,0)
scene.add(light3)
let light4=new THREE.DirectionalLight("#fff",1)
light4.position.set(0,10,0)
scene.add(light4)
let light5=new THREE.DirectionalLight("#fff",0.3)
light5.position.set(0,-10,0)
scene.add(light5)
let light6=new THREE.DirectionalLight("#fff",0.3)
light6.position.set(5,10,0)
scene.add(light6)
let light7=new THREE.DirectionalLight("#fff",0.3)
light7.position.set(0,10,5)
scene.add(light7)
let light8=new THREE.DirectionalLight("#fff",1)
light8.position.set(-5,10,5)
scene.add(light8)

//
let wheels=[]
let carBody,frontCar,hoodCar,glassCar







  //渲染器
  const renderder=new THREE.WebGLRenderer({
      antialias:true
  })
  renderder.setSize(window.innerWidth,window.innerHeight)
  renderder.setClearColor("#ccc")
  document.body.appendChild(renderder.domElement)
  
  //控制器
  const control=new OrbitControls(camara,renderder.domElement)
  
  
  //动画

  
  //渲染函数
  const render=()=>{
      renderder.render(scene,camara)
      requestAnimationFrame(render)
  }
  render()
  
  
  window.addEventListener("resize",()=>{
      camara.aspect=window.innerWidth/window.innerHeight;
      camara.updateProjectionMatrix()
  })
  
  const selectColor=(index)=>{
    console.log("colors[index]:",index)
    // bodyMaterial.color.set(colors[index].value.value)
    // frontMaterial.color.set(colors[index].value.value)
    // hoodMaterial.color.set(colors[index].value.value)

    bodyMaterial.color.set(colors[index].value)
    frontMaterial.color.set(colors[index].value)
    hoodMaterial.color.set(colors[index].value)
  }

  const selectMeterial=(index)=>{
    console.log("material[index]:",index)
    bodyMaterial.clearcoatRoughness=materials[index].value
    frontMaterial.clearcoatRoughness=materials[index].value
    hoodMaterial.clearcoatRoughness=materials[index].value
  }

  </script>
  <style  scoped>
  .a{
    color:#ac84eb
  }
  .colors{
    width: 600px;
    position:absolute;
    top:20px;
    right:0;
    z-index: 10;
    display: flex;
    justify-content: flex-end;
    padding-right:20px
  }
  .item{
    display: inline-block;
    padding: 3px 10px;
    margin-left:6px;
    text-align: center;
    color:#fff;
    border-radius:24px;
  }
  .material{
    width: 600px;
    position:absolute;
    top:60px;
    right:0;
    z-index: 10;
    display: flex;
    justify-content: flex-end;
    padding-right:20px
  }
  .material-item{
    display: inline-block;
    padding: 3px 10px;
    margin-left:6px;
    text-align: center;
    background:#333;
    color:#fff;
    border-radius:24px;
  }
  </style>

One thing to note here is the path to load the model:

const loader = new GLTFLoader();
const dracoLoader = new DRACOLoader();
dracoLoader.setDecoderPath("public/");
dracoLoader.preload();

loader.setDRACOLoader(dracoLoader);
loader.load("bmw01.glb", glb => {
  console.log("glb", glb);
  mesh = new THREE.Mesh(glb, new THREE.MeshStandardMaterial({ color: "#fff" }));
  scene.add(mesh);
  renderder.render(scene, camara);
});

In this case, there are four files in the public folder, namely draco_decoder, draco_decoder.wasm, draco_encoder.js, and draco_wasm_wrapper.js. They are used to parse the model. It must be noted that these four files must be placed in dracoLoader.setDecoderPath(" "); directory. Pay special attention to setDecoderPath() instead of setPath(). Previously, it was because the automatic completion was accidentally written as setPath, which caused the model loading to always report 404. If the parsed directory is set dracoLoader.setDecoderPath("public/model"); then These four files must be in the public/model directory. Second point: Pay attention to whether the versions of these four files are consistent with the three.js version of the current project. Otherwise it will not be parsed. The best way is to install the latest three.js package. At the same time, find the dev branch in the github of three.js, find the exa,ples/jsm/libs/draco directory, extract the four js files in this directory, namely draco_decoder, draco_decoder.wasm, draco_encoder.js, draco_wasm_wrapper.js, and put them in dracoLoader.setDecoderPath("");In the directory set,

Guess you like

Origin blog.csdn.net/baidu_41601048/article/details/128618763