阅读量:1
导入模型 改纹理
效果图
<template> <div> <h1>鞋模型</h1> <model-viewer style="width: 300px; height: 300px" id="my-replace-people" src="/imgApi/Astronaut.glb" auto-rotate camera-controls > </model-viewer> <h1>图片贴到模型上</h1> <div class="example-wrapper"> <model-viewer id="my-replace-shop" src="/imgApi/scene.gltf" auto-rotate camera-controls > <div class="controls" id="color-controls"> <button data-color="#ff0000">Red</button> <button data-color="#00ff00">Green</button> <button data-color="#0000ff">Blue</button> <button data-color="#ffffff">White</button> </div> <div id="progress-bar"></div> <!-- <template #progress-bar></template> --> </model-viewer> </div> <h1>原模型</h1> <!-- src="/imgApittps://res.theuniquer.com/pgc-models/picture.gltf" --> <model-viewer src="/imgApi/pgc-models_picture.gltf" auto-rotate camera-controls > </model-viewer> <h1>原图片</h1> <img style="width: 100%; height: 100px; object-fit: contain" src="/imgApi/tietu.jpg" alt="" /> <h1>图片贴到模型上</h1> <div class="example-wrapper"> <model-viewer id="my-replace-texture" src="/imgApi/pgc-models_picture.gltf" auto-rotate camera-controls > </model-viewer> </div> </div> </template> <script setup> import { ref, onMounted } from "vue"; import * as THREE from "three"; import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js"; import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader"; import Hammer from "hammerjs"; import { useEventListener } from "@vueuse/core"; import "@google/model-viewer"; const modelContainer = new THREE.Object3D(); const scene = new THREE.Scene(); const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 ); // 在创建渲染器时,添加antiallias:true抗锯齿,让模型看起来更加平滑 const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true }); // 设置画布分辨率 提高画质 renderer.setPixelRatio(window.devicePixelRatio); const loader = new GLTFLoader(); let model = null; // 光源设置 // const ambientLight = new THREE.AmbientLight(0xffffff, 0.5); // 环境光 // scene.add(ambientLight); // const pointLight = new THREE.PointLight(0xffffff, 1); // 点光源 // pointLight.position.set(10, 10, 10); // scene.add(pointLight); // 环境光 (这是一定要的) const ambientLight = new THREE.AmbientLight(0xffffff, 2); // scene.add(ambientLight); // 白色平行光(模型更明亮) const directionalLight = new THREE.DirectionalLight(0xffffff, 2); // 参数自行调整 directionalLight.position.x = 1; directionalLight.position.y = 1; directionalLight.position.z = 80; directionalLight.target = modelContainer; // target指向模型 scene.add(directionalLight); // *创建点光源(这个看情况给) var pointLight = new THREE.PointLight(0xffffff, 500); // 设置点光源的颜色和强度 pointLight.position.set(0, 0, 100); // 设置点光源的位置 scene.add(pointLight); // 设置阴影 renderer.shadowMap.enabled = true; renderer.shadowMap.type = THREE.PCFSoftShadowMap; // 初始化 Three.js 相关设置 camera.position.z = 5; renderer.setSize(window.innerWidth, window.innerHeight); function initControls() { const controls = new OrbitControls(camera, renderer.domElement); // 如果使用animate方法时,将此函数删除 //controls.addEventListener( 'change', render ); // 使动画循环使用时阻尼或自转 意思是否有惯性 controls.enableDamping = true; //动态阻尼系数 就是鼠标拖拽旋转灵敏度 //controls.dampingFactor = 0.25; //是否可以缩放 controls.enableZoom = true; //是否自动旋转 // controls.autoRotate = true; controls.autoRotateSpeed = 0.5; //设置相机距离原点的最远距离 // controls.minDistance = 1; //设置相机距离原点的最远距离 controls.maxDistance = 2000; //是否开启右键拖拽 controls.enablePan = true; } // 加载模型 loader.load("/imgApi/Astronaut.glb", (gltf) => { model = gltf.scene; model.castShadow = true; // 模型投射阴影 scene.add(model); }); // 设置容器 const container = ref(null); onMounted(() => { const fn = async (modelViewer) => { const targetMaterial = modelViewer.model.materials.find( (material) => material.name == "Center" ); //找到材质 console.log("targetMaterial="); console.log(modelViewer.model); console.log(modelViewer.model.materials); console.log(targetMaterial); const targetTexture = await modelViewer.createTexture( "/imgApi/red-huawen.jpg" ); // 用图片创建纹理 targetMaterial.pbrMetallicRoughness.baseColorTexture.setTexture( targetTexture ); }; const modelViewer = document.querySelector( "model-viewer#my-replace-texture" // "model-viewer#my-replace-shop" ); modelViewer.addEventListener("load", () => { fn(modelViewer); }); const modelViewerColor = document.querySelector( "model-viewer#my-replace-shop" ); const loadingText = document.getElementById("progress-bar"); const modelViewerPle = document.querySelector("#my-replace-people"); modelViewerPle.addEventListener("progress", (event) => { const loaded = event.detail.totalProgress; console.log("loading-->"); console.log(`${(loaded * 100).toFixed(0)}%`); if (loadingText) loadingText.innerHTML = `${(loaded * 100).toFixed(0)}%`; // loadingText.textContent = `${(loaded * 100).toFixed(0)}%`; }); modelViewerPle.addEventListener("load", async () => { const targetMaterial = modelViewerPle.model.materials.find( (material) => material.name == "Center" ); //找到材质 console.log("modelViewerPle----->"); console.log(modelViewerPle); console.log(modelViewerPle.model); console.log(modelViewerPle.model.materials); setTimeout(() => { loadingText.style.display = "none"; }, 100); const targetTexture = await modelViewer.createTexture( "/imgApi/red-huawen.jpg" ); // 用图片创建纹理 const [material] = modelViewerPle.model.materials; material.pbrMetallicRoughness.baseColorTexture.setTexture(targetTexture); }); modelViewerColor.addEventListener("load", async () => { const targetMaterial = modelViewerColor.model.materials.find( (material) => material.name == "Center" ); //找到材质 console.log("modelViewerColor----->"); console.log(modelViewerColor); console.log(modelViewerColor.model); console.log(modelViewerColor.model.materials); const targetTexture = await modelViewer.createTexture( "/imgApi/red-huawen.jpg" ); // 用图片创建纹理 const [material] = modelViewerColor.model.materials; material.pbrMetallicRoughness.baseColorTexture.setTexture(targetTexture); }); // const targetMateriaShop = modelViewerColor.model.materials.find( // (material) => material.name == "Center" // ); //找到材质 document .querySelector("#color-controls") .addEventListener("click", (event) => { const colorString = event.target.dataset.color; const [material] = modelViewerColor.model.materials; material.pbrMetallicRoughness.setBaseColorFactor(colorString); }); }); </script> <style scoped> .example-wrapper model-viewer { width: 50vw; height: 50vh; margin: 20vh auto 0; background-color: #fff; } </style>