导入模型 改纹理
效果图
<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>