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

news2024/9/21 14:46:38

导入模型 改纹理

 效果图

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1926548.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【棋盘上的战舰】python刷题记录

目录 小前言 思路&#xff1a; 上代码 lucky ending 小前言 经过漫长的停更周期-----1个月 我决定铁血回归&#xff01;&#xff01;&#xff01; 思路&#xff1a; 两层for循环暴力最快了这种小小范围题&#xff0c;主要是第一行和第一列的边界处理&#xff0c;我分为…

STM32MP135裸机编程:定时器内核时钟频率计算方法

0 工具准备 STM32MP13xx参考手册 1 定时器内核时钟频率计算方法 1.1 定时器分组 STM32MP135的定时器按照时钟源不同分成了三组&#xff0c;如下&#xff1a; APB1: APB2: APB6&#xff1a; 1.2 定时器内核时钟频率计算方法 APB1DIV是APB1的分频系数&#xff0c;APB2DIV、…

docker和docker的安装

1什么是docker&#xff1f; docker是容器技术&#xff08;软件&#xff09;&#xff0c;提供标准的应用镜像&#xff08;包含应用&#xff0c;和应用的依赖&#xff09;可以轻松在docker里安装应用&#xff0c;每个应用独立容器 2.主要功能&#xff1a; 打包&#xff08;软件…

Go:基本变量与数据类型

目录 前言 前期准备 Hello World! 一、基本变量 1.1 声明变量 1.2 初始化变量 1.3 变量声明到初始化的过程 1.4 变量值交换 1.5 匿名变量 1.6 变量的作用域 二、数据类型 1.1 整型 1.2 浮点型 1.3 字符串 1.4 布尔类型 1.5 数据类型判断 1.6 数据类型转换 1.…

STM32 BootLoader 刷新项目 (四) 通信协议

STM32 BootLoader 刷新项目 (四) 通信协议 文章目录 STM32 BootLoader 刷新项目 (四) 通信协议1. 通信流程2. 支持指令3. 通信流程4. 指令结构5. 操作演示 前面几章节&#xff0c;我们已经介绍了BootLoader的整体程序框架&#xff0c;方案设计&#xff0c;以及STM32CubdeMX的配…

51单片机6(P0P1P2P3结构框架图)

一、GPIO结构框架图与工作原理 1、接下来我们介绍一下这个GPIO结构框图和工作原理&#xff0c;我们使用51单片机的GPIO分为了P0&#xff0c;P1&#xff0c;P2&#xff0c;P3这四组端口&#xff0c;下面我们就分别来介绍这四组端口它的一个内部结构&#xff0c;只有了解了内部的…

Python爬虫入门篇学习记录

免责声明 本文的爬虫知识仅用于合法和合理的数据收集&#xff0c;使用者需遵守相关法律法规及目标网站的爬取规则&#xff0c;尊重数据隐私&#xff0c;合理设置访问频率&#xff0c;不得用于非法目的或侵犯他人权益。因使用网络爬虫产生的任何法律纠纷或损失&#xff0c;由使用…

MySQl高级篇-事务、锁机制、MVCC

存储引擎的选择 在选择存储引擎时&#xff0c;应该根据应用系统的特点选择合适的存储引擎。对于复杂的应用系统&#xff0c;还可以根据实际情况选择多种存储引擎进行组合。 InnoDB&#xff1a;是Mysql的默认存储引擎&#xff0c;支持事务、外键。如果应用对事务的完整性有比较…

C++知识要点总结笔记

文章目录 前言一、c基础1.指针和引用指针和引用的区别 2.数据类型整型 short int long 和 long long无符号类型 3.关键字conststaticconst和static的区别define 和 typedef 的区别define 和 inline 的区别const和define的区别new 和 malloc的区别constexprvolatileextern前置与…

用Speedtest-Tracker跟踪上网速度(续)

什么是 Speedtest Tracker ? Speedtest Tracker 是一款自托管互联网性能跟踪应用程序&#xff0c;可针对 Ookla 的 Speedtest 服务运行速度测试检查。 之前老苏介绍的另一个 https://github.com/henrywhitaker3/Speedtest-Tracker 已被放弃。现在这个是积极维护的替代品&#…

repo sync同步出错解决

当出现下面提示时 e list of known hosts. Fetching: 100% (1167/1167), done in 44.619s info: A new version of repo is available warning: repo is not tracking a remote branch, so it will not receive updates Repo command failed: RepoUnhandledExceptionError …

element UI时间组件两种使用方式

加油&#xff0c;新时代打工&#xff01; 组件官网&#xff1a;https://element.eleme.cn/#/zh-CN/component/date-picker 先上效果图&#xff0c;如下&#xff1a; 第一种实现方式 <div class"app-container"><el-formref"submitForm":model&q…

Zabbix6.0监控Freeswitch状态

一、前提环境说明 1、最终实现Freeswitch监控指标信息&#xff1a; 2、环境需求&#xff1a; &#xff08;1&#xff09;需要使用Zabbix6.0及以上 &#xff08;2&#xff09;需要使用zabbix_agent2 二、实现步骤 1、zabbix_agent2添加监控键值 cat /etc/zabbix/conf.d/fr…

Git代码管理工具 — 3 Git基本操作指令详解

目录 1 获取本地仓库 2 基础操作指令 2.1 基础操作指令框架 2.2 git status查看修改的状态 2.3 git add添加工作区到暂存区 2.4 提交暂存区到本地仓库 2.5 git log查看提交日志 2.6 git reflog查看已经删除的记录 2.7 git reset版本回退 2.8 添加文件至忽略列表 1 获…

2.有限状态机

1. 标准三段式写法&#xff1a; 1.一段代表当前状态赋值&#xff1b; 2.一段代表下一个状态如何跳变 3.一段代表输出控制 一定要带上复位 前两段模板集合一样&#xff0c;第三段取决于具体需求 parameter IDLE_ST 4b0000&#xff1b; parameter TEST_ST 4b0001; ... re…

C++中链表的底层迭代器实现

大家都知道在C的学习中迭代器是必不可少的&#xff0c;今天我们学习的是C中的链表的底层迭代器的实现&#xff0c;首先我们应该先知道链表的底层迭代器和顺序表的底层迭代器在实现上有什么区别&#xff0c;为什么顺序表的底层迭代器更加容易实现&#xff0c;而链表的底层迭代器…

Ubuntu20.04 编译安装FFmpeg,出错分析以及解决方案

最近工程上需要对FFmpeg底层源码进行修改&#xff0c;需要重新编译&#xff0c;遇见不少坑&#xff0c;出篇教程记录一下。 文章目录 1.FFmpeg源码下载地址2.编译环境配置3.编译FFmpeg4.配置FFmpeg运行环境 1.FFmpeg源码下载地址 官方下载地址:Index of /releases (ffmpeg.or…

使用MovaXterm连接VMware的centos

一、确认局域网ip 检查虚拟机分配的网段是否一致 二、确认centos的ip 输入 ip addr 获得设备ip为192.168.153.130 三、用MovaXterm建立ssh连接 有同行可能会问&#xff0c;直接使用VMware操作centos系统不行吗&#xff1f;为什么要再多一步。 理由&#xff1a;1、测试环境c…

Zabbix6.0使用自带模板(MySQL by Zabbix agent 2)监控MySQL数据库

注意&#xff1a;Zabbix6.0使用MySQL by Zabbix agent 2 模板可直接监控MySQL数据库&#xff0c;只需要创建监控用户&#xff0c;模板宏中填写数据库账号信息即可&#xff0c;只需要3步&#xff0c;特简单&#xff01; 1、MySQL创建用户&#xff0c;用于收集数据库信息 creat…

HarmonyOS 界面开发基础篇

一、布局思路 ArkUI(方舟开发框架)是一套 构建 鸿蒙应用 界面 的框架。 构建页面的最小单位就是“组件”。 组件分类 基础组件&#xff1a;界面呈现的基础元素。 如&#xff1a;文字、图片、按钮等。容器组件&#xff1a;控制布局排布。 如&#xff1a;Row行、Column列等。…