@google/model-viewer 导入 改纹理 (http-serve)

导入模型 改纹理

效果图

javascript 复制代码
<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>
相关推荐
燃先生._.1 小时前
Day-03 Vue(生命周期、生命周期钩子八个函数、工程化开发和脚手架、组件化开发、根组件、局部注册和全局注册的步骤)
前端·javascript·vue.js
高山我梦口香糖2 小时前
[react]searchParams转普通对象
开发语言·前端·javascript
black^sugar3 小时前
纯前端实现更新检测
开发语言·前端·javascript
2401_857600954 小时前
SSM 与 Vue 共筑电脑测评系统:精准洞察电脑世界
前端·javascript·vue.js
2401_857600954 小时前
数字时代的医疗挂号变革:SSM+Vue 系统设计与实现之道
前端·javascript·vue.js
GDAL4 小时前
vue入门教程:组件透传 Attributes
前端·javascript·vue.js
小白学大数据4 小时前
如何使用Selenium处理JavaScript动态加载的内容?
大数据·javascript·爬虫·selenium·测试工具
轻口味5 小时前
Vue.js 核心概念:模板、指令、数据绑定
vue.js
2402_857583495 小时前
基于 SSM 框架的 Vue 电脑测评系统:照亮电脑品质之路
前端·javascript·vue.js