导入模型 改纹理
效果图
<template><div><h1>鞋模型</h1><model-viewerstyle="width: 300px; height: 300px"id="my-replace-people"src="/imgApi/Astronaut.glb"auto-rotatecamera-controls></model-viewer><h1>图片贴到模型上</h1><div class="example-wrapper"><model-viewerid="my-replace-shop"src="/imgApi/scene.gltf"auto-rotatecamera-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-viewersrc="/imgApi/pgc-models_picture.gltf"auto-rotatecamera-controls></model-viewer><h1>原图片</h1><imgstyle="width: 100%; height: 100px; object-fit: contain"src="/imgApi/tietu.jpg"alt=""/><h1>图片贴到模型上</h1><div class="example-wrapper"><model-viewerid="my-replace-texture"src="/imgApi/pgc-models_picture.gltf"auto-rotatecamera-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>