Threejs 예제 10: 자동차 모델 전시회


<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>

여기서 주목해야 할 한 가지는 모델을 로드하는 경로입니다.

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);
});

이 경우 public 폴더에는 draco_decoder, draco_decoder.wasm, draco_encoder.js, draco_wasm_wrapper.js 4개의 파일이 있으며, 이는 모델을 구문 분석하는 데 사용됩니다. 이 4개의 파일은 dracoLoader에 있어야 한다는 점에 유의해야 합니다. .setDecoderPath(" "); 디렉토리. setPath() 대신 setDecoderPath() 에 특히 주의하세요 . 이전에는 자동 완성이 실수로 setPath로 작성되어 모델 로딩이 항상 404를 보고했기 때문이었습니다. 구문 분석된 디렉터리가 설정된 경우 dracoLoader.setDecoderPath("public/ model"); 그런 다음 이 4개 파일은 public/model 디렉터리에 있어야 합니다. 두 번째 사항: 이 4개 파일의 버전이 현재 프로젝트의 three.js 버전과 일치하는지 주의하세요. 그렇지 않으면 구문 분석되지 않습니다. 가장 좋은 방법은 최신 three.js 패키지를 설치하는 것입니다. 동시에 three.js의 github에서 dev 브랜치를 찾고 exa, ples/jsm/libs/draco 디렉터리를 찾고 이 디렉터리에서 4개의 js 파일, 즉 draco_decoder, draco_decoder.wasm, draco_encoder.js를 추출합니다. draco_wasm_wrapper.js를 작성하고 dracoLoader.setDecoderPath("")에 넣습니다. 디렉토리 세트에서,

Supongo que te gusta

Origin blog.csdn.net/baidu_41601048/article/details/128618763
Recomendado
Clasificación