three.js加载PLY格式模型(vue中使用three.js56)

2023-11-09

1.demo效果

在这里插入图片描述

如上图,该demo通过PLYLoader加载了PLY格式的模型,将汽车模型呈现在页面中

2.实现要点

2.1 PLY模型放置路径

vue中加载文件时默认的路径为public下,所以需要加载的文件放在该路径下,同时在vue的data属性中创建变量publicPath,此变量的值是vue中的环境变量process.env.BASE_URL

data() {
  return {
    publicPath: process.env.BASE_URL
  }
}

2.2 加载PLY模型

这我们通过PLYLoader导入模型,不过这里需要注意导入的路径,把我们创建的publicpath变量拼接到文件的路径上,在导入的回调函数中可以进行相关处理具体如下:

const loader = new PLYLoader()
loader.load(`${THIS.publicPath}models/test.ply`, model => {
	//对导入模型进行相关处理
	...
})

2.3 创建粒子材质纹理

//生成纹理
generateSprite() {
  const canvas = document.createElement('canvas')
  canvas.width = 16
  canvas.height = 16

  const context = canvas.getContext('2d')
  const gradient = context.createRadialGradient(
    canvas.width / 2,
    canvas.height / 2,
    0,
    canvas.width / 2,
    canvas.height / 2,
    canvas.width / 2
  )
  gradient.addColorStop(0, 'rgba(255,255,255,1)')
  gradient.addColorStop(0.2, 'rgba(0,255,255,1)')
  gradient.addColorStop(0.4, 'rgba(0,0,64,1)')
  gradient.addColorStop(1, 'rgba(0,0,0,1)')

  context.fillStyle = gradient
  context.fillRect(0, 0, canvas.width, canvas.height)

  const texture = new THREE.Texture(canvas)
  texture.needsUpdate = true
  return texture
}

2.4 格式化为粒子系统

// 创建粒子材质
const material = new THREE.PointsMaterial({
  color: 0xffffff,
  size: 0.4,
  opacity: 0.6,
  transparent: true,
  blending: THREE.AdditiveBlending,
  map: this.generateSprite()
})
// 创建粒子系统
this.mesh = new THREE.Points(geometry, material)
// 添加到场景
this.scene.add(this.mesh)

3.demo代码

<template>
  <div>
    <div id="container"></div>
  </div>
</template>

<script>
import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'
import { PLYLoader } from 'three/examples/jsm/loaders/PLYLoader.js'

export default {
  data() {
    return {
      publicPath: process.env.BASE_URL,
      mesh: null,
      camera: null,
      scene: null,
      renderer: null,
      controls: null
    }
  },
  mounted() {
    this.init()
  },
  methods: {
    // 初始化
    init() {
      this.createScene() // 创建场景
      this.loadPLY() // 加载PLY模型
      this.createLight() // 创建光源
      this.createCamera() // 创建相机
      this.createRender() // 创建渲染器
      this.createControls() // 创建控件对象
      this.render() // 渲染
    },
    // 创建场景
    createScene() {
      this.scene = new THREE.Scene()
    },
    // 加载PLY模型
    loadPLY() {
      const THIS = this
      const loader = new PLYLoader()
      loader.load(`${THIS.publicPath}models/test.ply`, geometry => {
        // 创建粒子材质
        const material = new THREE.PointsMaterial({
          color: 0xffffff,
          size: 0.4,
          opacity: 0.6,
          transparent: true,
          blending: THREE.AdditiveBlending,
          map: this.generateSprite()
        })
        // 创建粒子系统
        this.mesh = new THREE.Points(geometry, material)
        // 添加到场景
        this.scene.add(this.mesh)
      })
    },
    //生成纹理
    generateSprite() {
      const canvas = document.createElement('canvas')
      canvas.width = 16
      canvas.height = 16

      const context = canvas.getContext('2d')
      const gradient = context.createRadialGradient(
        canvas.width / 2,
        canvas.height / 2,
        0,
        canvas.width / 2,
        canvas.height / 2,
        canvas.width / 2
      )
      gradient.addColorStop(0, 'rgba(255,255,255,1)')
      gradient.addColorStop(0.2, 'rgba(0,255,255,1)')
      gradient.addColorStop(0.4, 'rgba(0,0,64,1)')
      gradient.addColorStop(1, 'rgba(0,0,0,1)')

      context.fillStyle = gradient
      context.fillRect(0, 0, canvas.width, canvas.height)

      const texture = new THREE.Texture(canvas)
      texture.needsUpdate = true
      return texture
    },

    // 创建光源
    createLight() {
      // 环境光
      const ambientLight = new THREE.AmbientLight(0xffffff, 0.1) // 创建环境光
      this.scene.add(ambientLight) // 将环境光添加到场景

      const spotLight = new THREE.SpotLight(0xffffff) // 创建聚光灯
      spotLight.position.set(50, 50, 50)
      spotLight.castShadow = true
      this.scene.add(spotLight)
    },
    // 创建相机
    createCamera() {
      const element = document.getElementById('container')
      const width = element.clientWidth // 窗口宽度
      const height = element.clientHeight // 窗口高度
      const k = width / height // 窗口宽高比
      // PerspectiveCamera( fov, aspect, near, far )
      this.camera = new THREE.PerspectiveCamera(35, k, 0.1, 1000)
      this.camera.position.set(20, 20, 20) // 设置相机位置

      this.camera.lookAt(new THREE.Vector3(10, 40, 0)) // 设置相机方向
      this.scene.add(this.camera)
    },
    // 创建渲染器
    createRender() {
      const element = document.getElementById('container')
      this.renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true })
      this.renderer.setSize(element.clientWidth, element.clientHeight) // 设置渲染区域尺寸
      this.renderer.shadowMap.enabled = true // 显示阴影
      this.renderer.shadowMap.type = THREE.PCFSoftShadowMap
      this.renderer.setClearColor(0x3f3f3f, 1) // 设置背景颜色
      element.appendChild(this.renderer.domElement)
    },

    render() {
      if (this.mesh) {
        this.mesh.rotation.y += 0.006
      }
      this.renderer.render(this.scene, this.camera)
      requestAnimationFrame(this.render)
    },
    // 创建控件对象
    createControls() {
      this.controls = new OrbitControls(this.camera, this.renderer.domElement)
    }
  }
}
</script>
<style>
#container {
  position: absolute;
  width: 100%;
  height: 100%;
}
</style>

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

three.js加载PLY格式模型(vue中使用three.js56) 的相关文章

  • javascript 正则表达式用于空格或

    我正在寻找一个用于空白的 javascript 正则表达式 我正在循环中检查几个不同的字符串 我需要找到其中有大空白的字符串 空白字符串构建在一个循环中 就像这样 请将此代码阅读为var whitespace nbsp 然后循环只是在其上连
  • 使用 ScriptEngine 从 JavaScript 调用 Java 方法

    我正在使用 ScriptEngine 运行 JavaScript 我希望 JavaScript 脚本能够调用 myFunction 其中 myFunction 是我的给定类中的一个方法 我知道可以将 importPackage 用于标准 J
  • 如何使用nodeJS SFTP客户端列出所有子目录?

    有趣的节点 JS ssh2 sftp client 我想列出给定路径中的所有目录及其子目录 let sftp new ssh2SftpClient console log sftp sftp connect host xx xxx xxx
  • angularjs 自定义过滤器检查数据数组内的值

    我有两个过滤器 它们根据数据中的队列键过滤数据 这是我的代码 var app angular module app app controller mainController function scope Data object scope
  • 从 Angular 6 服务中绑定图像

    我有一个端点 它根据某些参数为我提供图像 这不是一个图像网址 而是一个普通图像 因此 当我到达邮递员中的端点时 作为响应 我收到一张图像 JPG 我是否可以在变量中接收该图像并将其绑定到 HTML 标签中 所有问题都有将图像 url 映射到
  • 使用 word_number 值对 javascript 数组进行排序

    如何对数组进行排序 var arr new Array word 12 word 59 word 17 这样我得到 word 12 word 17 word 59 Thanks 您需要编写一个排序方法 您可以编写任何您喜欢的方法 该方法在
  • 为什么新行上的 return 语句不返回任何值? [复制]

    这个问题在这里已经有答案了 考虑以下情况 function func1 return hello world function func2 return hello world console log func1 console log f
  • 使用 getElementById 在 javascript 中使用正则表达式进行 Html 表单验证?

    我想使用正则表达式验证 html 表单的示例模式 AAA 111 2222 aa 1234 目前 我的代码要么为所有输入返回 正确 要么为所有输入返回 不正确 并且我无法弄清楚我的问题出在哪里 var x document getEleme
  • 拖放图像上传在服务器上不起作用

    我正在尝试实现拖放图像上传 我在网上找到了一个相当简单的脚本并适合我的使用 在我的本地安装中 文件上传得很好 但在服务器上却不行 从我的调试尝试来看 SERVER HTTP X FILENAME 甚至没有被 php 设置 我尝试了以下方法
  • Angular UI.Bootstrap 单选按钮在 ng-repeat 中表现得很奇怪[重复]

    这个问题在这里已经有答案了 我在 Angular 的 ui bootstrap 中动态生成无线电模型的选项时遇到问题 我想我可以简单地对数组进行 ng repeat 使用 btn radio 属性的内容 如下所示 in the contro
  • 表单提交不起作用

    我有一张桌子 可以打印出所有可用的相机 它使用表单来更改这些设置 问题在于该表单仅更新条目中的最后一个摄像机 换句话说 如果我更改表单并为列表中的最后一个摄像机点击 应用 它将起作用 如果我更改此列表中任何其他摄像机的表单 它会将其更改为与
  • Google Maps JS Api - b.get 不是函数错误(isLocationOnEdge)

    我想检查我的路线上是否有标记 所以我尝试使用 isLocationOnEdge 但收到 TypeError b get 不是函数 错误 这是我的代码 我尝试了几次更改但无法解决问题 var directionsDisplay new goo
  • 为什么在 vue 组件上输入另一个输入时,输入文件的值丢失了?

    我有两个组件 我的第一个组件 父组件 如下所示
  • jQuery 面板滑块通过单击按钮打开但不会关闭

    我的页面上有一个按钮 可以使用 jquery 和 Modernizr 框架打开右侧面板 按钮位于屏幕最右侧 单击时 它会向左滑动并打开打开的面板 问题是 再次单击时它不会滑回到原来的位置 HTML div class cd panel fr
  • Niceedit本地上传图片失败

    我是这样称呼编辑的 new nicEditor buttonList bold italic underline upload iconsPath img nicedit png uploadURI http server com inte
  • 是否可以从 webpack 中的文件名中删除特殊字符?

    长话短说 我的资产文件名中不能包含某些字符 例如连字符 我没有运气通过解析 webpack 文档来弄清楚是否可以使用正则表达式或类似的东西重命名文件 这样我就可以从我无法控制源文件名的 3rd 方包中删除任何连字符 我的超级天真的例子是这样
  • jVectorMap - 向下钻取地图 - 自定义背景

    我正在使用 jVectorMap 中的向下钻取地图 并且尝试将自定义背景颜色设置为地图的第二层 为了自定义主级别 我使用 main 参数 但我不知道如何将其扩展到地图的较低级别 提前致谢 马切伊 None
  • 更改 CSS 样式表的选择器属性

    以下是我们传统上如何更改重复元素的样式 将样式应用到每个元素 function changeStyle selector prop val var elems document querySelectorAll selector Array
  • 在64位环境中加载32位进程

    我有以下几个问题 CHM 是 编译的 HTML 文件 我的 CHM 文件有一个启动 32 位应用程序的链接 CHM 文件是用 Javascript 编码的 这在 32 位操作系统环境中运行良好 但这在 64 位操作系统环境中不起作用 原因是
  • 谷歌地图绘制两点之间的路线

    我编写了这段无辜的 JavaScript 代码 它允许用户创建两个标记并绘制它们之间的路线 它不起作用 相反 它给出了一个奇怪的错误 Uncaught TypeError Cannot read property ya of undefin

随机推荐

  • C#中导出百万级Excel只需几秒除了NPOI还可以这样

    场景 Winform中通过NPOI导出Excel的三种方式 HSSFWorkbook XSSFWorkbook SXSSFWorkbook 附代码下载 https blog csdn net BADAO LIUMANG QIZHI arti
  • 剪格子 蓝桥杯 211

    题目描述 如下图所示 3 x 3 的格子中填写了一些整数 我们沿着图中的红色线剪开 得到两个部分 每个部分的数字和都是 60 本题的要求就是请你编程判定 对给定的 m n 的格子中的整数 是否可以分割为两个部分 使得这两个区域的数字和相等
  • com.alibaba.fastjson.JSONArray cannot be cast to com.alibaba.fastjson.JSONObject

    json中类型转换问题 是错误的格式 例 JSONObject parseObject type slider show true start 1 end 100 正确的写法 JSONObject dataZoom new JSONObje
  • C# 委托(delegate)

    1 什么是委托 委托是一种引用类型 它是函数指针的托管版本 在C 中 委托是一种可以把引用存储为函数的类型 委托可以引用实例和静态方法 而函数指针只能引用静态方法 委托的声明非常类似于函数 和函数不同的的是委托不带函数体 并且需要Deleg
  • 初识Spring Boot

    目录 一 Spring Boot是什么 二 创建Spring Boot项目 1 使用IDEA创建 2 网页版创建 三 运行项目 一 Spring Boot是什么 简单来说Spring Boot就是Spring的 脚手架 就是一个框架 Spr
  • nodejs libuv学习

    读了一下libuv源代码 简单记录一些见解 https github com libuv libuv libev就是一个基于epoll封装事件的函数库 自身不带有线程池等操作 而libuv则是在libev基础上 加上线程操作的功能 大体运作
  • Java中Array.sort()的几种用法

    转载https www tuicool com articles iii6N3 Java的Arrays类中有一个sort 方法 该方法是Arrays类的静态方法 在需要对数组进行排序时 非常的好用 但是sort 的参数有好几种 下面我就为大
  • 【QT控件大小自适应窗口变化】

    问题 刚开始学习QT时 在窗口中放置一个个控件 而后运行程序 会发现改变窗口大小时 控件大小不随窗口大小变化而变化 导致窗口大小变化没意义 同时也让精心布局看起来很难看 本文提供一种使用BoxLayout中放置控件 所有可见控件能够随窗口大
  • 同仁堂-十大王牌、十大名药

    同仁堂 十大王牌 十大名药 官网 ZY123 com 中医123
  • WPS中编辑Word删除内容之后保存退出了如何恢复?

    目录 一 问题简述 二 Word用户 场景一 情况一 删除了内容没有退出文档 情况二 删除了内容退出文档 情况三 删除了文件退出文档 三 Wps用户 场景二 情况一 删除了内容没有退出文档 情况二 删除了内容退出文档 情况三 删除了文件退出
  • PAT 5 剪邮票

    剪邮票 如 图1 jpg 有12张连在一起的12生肖的邮票 现在你要从中剪下5张来 要求必须是连着的 仅仅连接一个角不算相连 比如 图2 jpg 图3 jpg 中 粉红色所示部分就是合格的剪取 请你计算 一共有多少种不同的剪取方法 请填写表
  • Flink从入门到真香(18、使用flink table api 从文件和kafka中读取数据)

    还是一样 要先引入依赖 在pom xml
  • java 数组排序(冒泡排序、快速排序、简单排序)

    目录 1 冒泡排序 2 快速排序 3 简单排序 1 冒泡排序 简介 1 循环遍历数组 判断相邻两个元素大小如果满足条件list x gt list x 1 则将两个元素位置对换 2 重复步骤 1 判断初始元素向右依次递减 3 一般有两层循环
  • win10桌面计算机不显示桌面,win10桌面不见了,win10桌面显示不了任何程序

    解决方法 首先 由于图标缓存文件是隐藏文件 我们需要在资源管理器中将zd设置改为 显示所有文件 操作方法 1 随便打开一个文件夹 2 点击 查看 菜单 然后勾选 隐藏的项目 同时按下快捷键 Win R 在打开的运行窗口中输版入 locala
  • 怎么分析用户活跃、指标波动

    相关文章 用户画像 3种标签类型 8大系统模块 知道用户画像标签有哪些维度 应用场景体系 是种什么样的体验 用户运营 用户分析 店铺数据分析 小程序数据分析 思维导图 数据分析全知识 思维导图 Xmind思维导图 常用快捷键使用 参考作者
  • 计算机视觉:图像检测和图像分割有什么区别?

    人工智能中的图像处理 人工智能对于图像处理有不同的任务 在本文中 我将介绍目标检测和图像分割之间的区别 在这两个任务中 我们都希望找到图像中某些感兴趣的项目的位置 例如 我们可以有一组安全摄像头照片 在每张照片上 我们想要识别照片中所有人的
  • 怎么查看mysql密码

    MySQL数据库查看密码的方法如下 以系统管理员身份运行cmd 查看mysql是否已经启动 如果已经启动 就停止 net stop mysql 切换到MySQL安装路径下 D WAMPMySQL 5 6 36in 如果已经配了环境变量 可以
  • LLVM-Clang编译器安装和使用

    LLVM不仅仅是一个编译器 同时提供了模块化的功能和库 用于编译器的开发和功能扩展 常规的一个编译器分为前端 优化器和后端 LLVM编译器也不例外 Clang就是属于一个编译器的前端部分 LLVM属于优化器和后端 当然LLVM也可以支持其他
  • C++常用算术生成算法剖析

    C STL库中常用生成算术算法有 accumulate 和 fill 在调用这些算法之前需要包含头文件 include
  • three.js加载PLY格式模型(vue中使用three.js56)

    加载PLY格式模型 1 demo效果 2 实现要点 2 1 PLY模型放置路径 2 2 加载PLY模型 2 3 创建粒子材质纹理 2 4 格式化为粒子系统 3 demo代码 1 demo效果 如上图 该demo通过PLYLoader加载了P