Vue3使用Three.js导入gltf模型并解决模型为黑色的问题

news2024/11/23 17:00:17

背景

如今各类数字孪生场景对三维可视化的需求持续旺盛,因为它们可以用来创建数字化的双胞胎,即现实世界的物体或系统的数字化副本。这种技术在工业、建筑、医疗保健和物联网等领域有着广泛的应用,可以帮助人们更好地理解和管理现实世界的事物。

Three.js 可以让我们在网页上创建交互式的 3D 图形和动画。它是一个强大的 JavaScript 库,可以帮助我们轻松地在浏览器中实现复杂的 3D 效果,而无需深入了解底层的 WebGL 技术。如果你需要在网页上展示 3D 内容或者构建交互式的3D体验, Three.js 是一个非常有用的工具。今天通过 Vue3.0 集成 Three.js 来实现对 gltf 模型的加载、渲染与操控。

下载模型

如果没有专门的三维建模工程师,可以到https://sketchfab.com注册一个账号,上面有不少可以免费下载的模型,我这里下载 gltf 格式。

2023-12-17-ModelSite.jpg

查看模型

这个 gltf 格式的文件可以使用 Win10 自带的 3D查看器 打开。

2023-12-17-Win103D.jpg

环境准备

Note:

  1. 前提需要有 Node.js 环境,可使用 nvm 进行 Node.js 的多版本管理。
  2. npm install <package>默认会在依赖安装完成后将其写入package.json,因此安装依赖的命令都未附加save参数。
$ node -v
v16.18.0

安装vue-cli并创建项目

npm install -g @vue/cli
vue --version
vue create three-gltf

刚开始的 package.json 依赖是这样:

  "dependencies": {
    "core-js": "^3.8.3",
    "vue": "^3.2.13"
  },

集成Three.js

  • 安装依赖
npm install three

此时, package.json 的依赖变为:

  "dependencies": {
    "core-js": "^3.8.3",
    "three": "^0.159.0",
    "vue": "^3.2.13"
  },

HelloWorld.vue 并列,创建一个 ThreeDemo.vue ,后续的三维场景渲染就在这个文件中实现,以下是完整代码。

<template>
  <div ref="threeModel" class="threed"></div>
</template>

<script setup>
import { ref, onMounted } from "vue";
import * as THREE from "three";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";

const threeModel = ref(null);
let scene, camera, renderer;

onMounted(() => {
  // 相机配置
  camera = new THREE.PerspectiveCamera(
    75,
    window.innerWidth / window.innerHeight,
    1,
    100
  );
  camera.position.set(3, 3, 3);
  camera.lookAt(0, 0, 0);

  // 渲染配置
  renderer = new THREE.WebGLRenderer({
    antialias: true, // 抗锯齿
    alpha: true, // 用于设置透明度
  });
  renderer.setSize(window.innerWidth, window.innerHeight);

  // 设置背景颜色
  renderer.setClearColor(0x000000, 0);

  // 场景初始化
  scene = new THREE.Scene();
  scene.add(new THREE.AmbientLight(0x666666)); // 环境光

  //添加模型
const loader = new GLTFLoader();
loader.load(
    "/static/model/scene.gltf",
    (gltf) => {
        // 解决模型为黑色的问题
        gltf.scene.traverse(function(child) {
            if (child.isMesh) {
                child.material.emissive = child.material.color;
                child.material.emissiveMap = child.material.map;
            }
        });
        scene.add(gltf.scene);
    },
    function(xhr) {
        // 控制台查看加载进度xhr
        console.log(Math.floor((xhr.loaded / xhr.total) * 100));
    }
);

  // 添加模型到页面
  threeModel.value.appendChild(renderer.domElement);

  //添加控制器
  let controls = new OrbitControls(camera, renderer.domElement);
  controls.addEventListener("change", () => {
    renderer.render(scene, camera);
  });
});
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
.threed {
  widows: 100%;
  height: 100%;
}
</style>

为了让 Vue 项目展示我们的三维模型页面,这里简单粗暴地将 HelloWorld.vue 替换了。

2023-12-17-DisplayModel.jpg

可能遇到问题

如何设置模型为透明背景?

有些场景下,比如我们要做数据大屏可视化,大屏本身已经有背景图片了,不希望 Three.js 的背景色遮挡,这时就可以将 Three.js 的背景设置为透明,设置背景透明前要先将 alpha 设置为 true ;通过 renderer.setClearColor(0x000000, 0) 第二个参数来设置透明度0是完全透明,1是不透明,可以按需调整0-1之间的数,eg: 0.8。

  // 相机配置
  camera = new THREE.PerspectiveCamera(
      75,
      window.innerWidth / window.innerHeight,
      1,
      100
  );

  // 渲染配置
  renderer = new THREE.WebGLRenderer({
      antialias: true, // 抗锯齿
      alpha: true, // 用于设置透明度
  });
  renderer.setSize(window.innerWidth, window.innerHeight);

  // 设置背景颜色,透明
  renderer.setClearColor(0x000000, 0);

Three.js导入gltf的模型黑乎乎的,怎么破?

2023-12-17-BlackModel.jpg
直接上解决办法:将模型的材质里的 emssive 设置为 material.color ,如果材质里有纹理,再把 emissiveMap 设置为 material.map

//添加模型
const loader = new GLTFLoader();
loader.load(
    "/static/model/scene.gltf",
    (gltf) => {
        // 解决模型为黑色的问题
        gltf.scene.traverse(function(child) {
            if (child.isMesh) {
                child.material.emissive = child.material.color;
                child.material.emissiveMap = child.material.map;
            }
        });
        scene.add(gltf.scene);
    },
    function(xhr) {
        // 控制台查看加载进度xhr
        console.log(Math.floor((xhr.loaded / xhr.total) * 100));
    }
);
  • 使用效果

2023-12-17-Demo

小总结

通过 Vue3.0 集成 Three.js ,可以在网页上展示 3D 内容或构建交互式的 3D 体验。在集成过程中,需要安装 Three.js 依赖并创建 ThreeDemo.vue 文件,然后通过 GLTFLoader 加载模型并解决模型为黑色的问题。同时,可以设置 Three.js 的背景为透明以适应不同场景需求。

Reference

  • https://sketchfab.com

If you have any questions or any bugs are found, please feel free to contact me.

Your comments and suggestions are welcome!

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

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

相关文章

Selenium框架的使用心得(一)

最近使用selenium框架实现业务前端的UI自动化&#xff0c;在使用selenium时&#xff0c;有一些心得想要和大家分享一下~ Selenium是一款用于web应用程序测试的工具&#xff0c;常用来实现稳定业务的UI自动化。这里&#xff0c;不想对其发展历史做介绍&#xff0c;也不想用官方…

EXCEL SUM类函数

参考资料 万能函数SUMPRODUCT超实用的10种经典用法 目录 一. SUM二. SUMIF2.1 统计贾1的销售额2.2 > 900 的销售总额2.3 计算贾1和贾22的销售总额2.4 多区域计算 三. SUMIFS3.1 统计苹果&#xff0c;在第一季度的总数量3.2 统计苹果&#xff0c;在第一季度&#xff0c;>…

智能家居和智能家居控制设备有什么区别?

智能家居和智能家居控制设备在功能和用途伤的区别&#xff1a; 智能家居是一种整体的概念&#xff0c;它涵盖了整个家庭环境的智能化&#xff0c;包括智能家电、智能照明、智能安防等设备的互联互通和协同工作。智能家居的目标是通过中央控制器或智能音箱等设备&#xff0c;实现…

Python内置函数一览表

为了提高程序员的开发效率&#xff0c;Python 提供了很多可以直接拿来用的函数&#xff08;初学者可以先理解为方法&#xff09;&#xff0c;每个函数都可以帮助程序员实现某些具体的功能。 举个例子&#xff0c;在 Python 2.x 中 print 只是一个关键字&#xff0c;但在 Pytho…

cefsharp120.1.8(cef120.1.8,Chromium120.0.6099.109)版本升级测试,其他版本H264版本

此版本最新版cef120.1.8,Chromium120.0.6099.109 此更新包括一个高优先级安全更新 This update includes a high priority security update. 说明&#xff1a;本版本暂时不支持264&#xff0c;其他H264版本参考119,116&#xff0c;114&#xff0c;110&#xff0c;109等版本 c…

Spring 原理(一)

Spring 原理 它是一个全面的、企业应用开发一站式的解决方案&#xff0c;贯穿表现层、业务层、持久层。但是 Spring仍然可以和其他的框架无缝整合。 Spring 特点 轻量级控制反转面向切面容器框架集合 Spring 核心组件 Spring 常用模块 Spring 主要包 Spring 常用注解 bean …

CUDA C:线程、线程块与线程格

相关阅读 CUDA Chttps://blog.csdn.net/weixin_45791458/category_12530616.html?spm1001.2014.3001.5482 第一百篇博客&#xff0c;写点不一样的。 当核函数在主机端被调用时&#xff0c;它会被转移到设备端执行&#xff0c;此时设备会根据核函数的调用格式产生对应的线程(…

如何应用基础故障编排?

基础故障编排是保障系统稳定性和可用性的关键环节。通过有效应用基础故障编排&#xff0c;组织能够更快速、更智能地应对系统故障&#xff0c;从而提升业务的可靠性和竞争力。本文将介绍如何应用基础故障编排! 1、选择合适的工具&#xff1a; 选择适合组织需求的基础故障编排工…

9. DashBoard

9. DashBoard 文章目录 9. DashBoard9.1 部署Dashboard9.2 使用DashBoard 在kubernetes中完成的所有操作都是通过命令行工具kubectl完成的。 为了提供更丰富的用户体验&#xff0c;kubernetes还开发了一个基于web的用户界面&#xff08;Dashboard&#xff09;。 用户可以使用…

Mysql之Specified key was too long; max key length is xx bytes异常

问题原因&#xff1a;mysq索引的字段都太长了 767字节是 MySQL 版本5.6(以及以前版本)中 InnoDB 表的最大索引前缀长度限制&#xff0c;MyISAM 表的长度为1,000字节。在 MySQL 版本5.7及以上版本中&#xff0c;这个限制增加到了3072字节。 如果对 utf8mb4编码的 varchar 字段设…

python+torch线性回归模型机器学习

程序示例精选 pythontorch线性回归模型机器学习 如需安装运行环境或远程调试&#xff0c;见文章底部个人QQ名片&#xff0c;由专业技术人员远程协助&#xff01; 前言 这篇博客针对《pythontorch线性回归模型机器学习》编写代码&#xff0c;代码整洁&#xff0c;规则&#xf…

【操作系统】实验四 进程调度

实验名称&#xff1a; 实验四 进程调度 实验目的&#xff1a; 1. 加深理解有关进程控制块、进程队列的概念 2. 体会和了解优先级和时间片轮转调度算法的具体实施办法 实验内容&#xff1a; 1. 设计进程控制块 PCB 表结构&#xff08;与实验一的结构相同&#xff09;&#xff…

超详细整理,Java接口自动化测试实战-rest-assured

1、关于rest-assured rest-assured 是一个能够简化测试rest服务的Java DSL&#xff0c;像ruby或者python一样的动态语言去测试和验证http服务。 基于java并且兼容了groovy动态语言的特性&#xff0c;使我们像写脚本语言一样去测试http服务。 例如&#xff1a;你的http服务&a…

范仲淹:文能治盛世,武可镇山河

北宋景佑元年&#xff08;公元1034&#xff09;年&#xff0c;范仲淹回乡祭拜范氏宗祠。在苏州祖宅住了几天后&#xff0c;范仲淹决定在苏州南园旁边买一块地&#xff0c;在此处盖一处房屋&#xff0c;待老迈时回乡居住。 按照家乡的风俗&#xff0c;在破土动工之前&#xff0c…

Note3---初阶二叉树~~

目录​​​​​​​ 前言&#x1f344; 1.树概念及结构☎️ 1.1 树的概念&#x1f384; 1.2 树的相关概念&#x1f99c; 1.2.1 部分概念的加深理解&#x1f43e; 1.2.2 树与非树&#x1fab4; 1.3 树的表示&#x1f38b; 1.4 树在实际中的运用&#xff08;表示文件系统…

软件试运行整体方案

一、 试运行目的 &#xff08;一&#xff09; 系统功能、性能与稳定性考核 &#xff08;二&#xff09; 系统在各种环境和工况条件下的工作稳定性和可靠性 &#xff08;三&#xff09; 检验系统实际应用效果和应用功能的完善 &#xff08;四&#xff09; 健全系统运行管理体…

Hadoop和Spark的区别

Hadoop 表达能力有限。磁盘IO开销大&#xff0c;延迟度高。任务和任务之间的衔接涉及IO开销。前一个任务完成之前其他任务无法完成&#xff0c;难以胜任复杂、多阶段的计算任务。 Spark Spark模型是对Mapreduce模型的改进&#xff0c;可以说没有HDFS、Mapreduce就没有Spark。…

架构简洁之道有感,谈谈软件组件聚合的张力

配图由腾讯混元助手生成 这篇文章介绍了软件架构设计中组件设计思想&#xff0c;围绕“组件间聚合的张力”这个有意思的角度&#xff0c;介绍了概念&#xff0c;并且结合架构设计示例对这个概念进行了进一步阐述。 组件聚合&#xff1f;张力&#xff1f;这标题&#xff0c;有种…

两位技术领导者的故事——英特尔和高通

对于科技行业来说&#xff0c;包括这样一个现实&#xff1a;上学、工作和娱乐实际上是未来生活的一部分。科技行业也面临着变革&#xff0c;行业内发生了几起重大收购和管理层变动。其中两个最具影响力的变化是英特尔和高通的换岗。具有讽刺意味的是&#xff0c;这两家公司在过…

UGUI 鼠标悬浮UI出现弹框,鼠标在图片边缘出现闪烁

1、背景&#xff1a;鼠标悬浮在UI上出现提示框 public class SpecialParam_list : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler {public void OnPointerEnter(PointerEventData eventData){TipBox.Instance.ShowBox(Input.mousePosition, value);}public void …