uniapp vue3中使用threejs渲染3D模型

这篇具有很好参考价值的文章主要介绍了uniapp vue3中使用threejs渲染3D模型。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言: 因为公司需求, 需要在App中内嵌一个3D模型. 在市场上看了一下情况, 大部分都是vue2的, 并没有vue3的版本...现在vue3也不是个新东西了. 后期模型会放入App内. 下面写法并不支持App(已解决在App中渲染, 关注我可见), 支持h5

template:

<template>
  <view class="">
    <view id="threeView">456</view>
    <view class="">
      22222
    </view>
  </view>
</template>

js:

<script module="three" lang="renderjs" setup>
  import * as THREE from 'three'
  //引入轨道控制器(用来通过鼠标事件控制模型旋转、缩放、移动)
  import {
    OrbitControls
  } from 'three/examples/jsm/controls/OrbitControls.js'
  import {
    GLTFLoader
  } from 'three/examples/jsm/loaders/GLTFLoader.js'
  import {
    FBXLoader
  } from 'three/examples/jsm/loaders/FBXLoader.js'
  import {
    computed,
    onMounted,
    ref,
    watch
  } from 'vue'
  // 如果模型没有显示出来, 可能是cameraZ的值不够, 请注意
  let scene = '',
    camera = '',
    renderer = '',
    cube = '',
    sphere = '',
    step = '',
    stats = '',
    group = '',
    cameraZ = 500,
    url = '../../static/Eraser(1).glb',
    width = 800,
    height = 560,
    orbitcontrols = '';
  const init = () => {
    console.log(cameraZ, 'cameraZ');
    scene = new THREE.Scene();
    camera = new THREE.PerspectiveCamera(45, width / height, 0.1, 1000);
    camera.position.set(0, 0, cameraZ);
    renderer = new THREE.WebGLRenderer({
      antialias: true
    });
    renderer.setClearColor(0xffffff, 0);
    renderer.setSize(width / 1.2, height / 1.2);
    renderer.setPixelRatio(window.devicePixelRatio);
    renderer.shadowMapEnabled = true;
    document.getElementById("threeView").appendChild(renderer.domElement);
    orbitcontrols = new OrbitControls(camera, renderer.domElement); //移动控件
    orbitcontrols.enabled = true;
    orbitcontrols.enableRotate = true;
    orbitcontrols.enableZoom = false;
    orbitcontrols.autoRotate = true;
    orbitcontrols.minPolarAngle = Math.PI / 4;
    orbitcontrols.maxPolarAngle = 3 - (Math.PI / 4);
    console.log('78', url.endsWith('gltf'), url.endsWith('glb'))
    console.log(url)
    if (url.endsWith('gltf') || url.endsWith('glb')) {
      //设置了六个平行光  有些材质不接受环境光会很暗
      const directionLight1 = new THREE.DirectionalLight(0xffffff, 1);
      directionLight1.position.set(-300, 0, 0)
      scene.add(directionLight1);

      const directionLight2 = new THREE.DirectionalLight(0xffffff, 1);
      directionLight2.position.set(300, 0, 0)
      scene.add(directionLight2);

      const directionLight3 = new THREE.DirectionalLight(0xffffff, 1);
      directionLight3.position.set(0, 300, 0)
      scene.add(directionLight3);

      const directionLight4 = new THREE.DirectionalLight(0xffffff, 1);
      directionLight4.position.set(0, 300, 0)
      scene.add(directionLight4);

      const directionLight5 = new THREE.DirectionalLight(0xffffff, 1);
      directionLight5.position.set(0, 0, -300)
      scene.add(directionLight5);

      const directionLight6 = new THREE.DirectionalLight(0xffffff, 1);
      directionLight6.position.set(0, 0, 300)
      scene.add(directionLight6);
    }
    let Sun = new THREE.DirectionalLight(0xffffff, 1);
    Sun.position.set(0, 300, 0);
    Sun.castShadow = true;
    let Ambient = new THREE.AmbientLight(0xffffff, 1);
    scene.add(Ambient);
    scene.add(Sun);
  }
  const loadModel = () => {
    let loader1 = new GLTFLoader();
    let FBXloader = new FBXLoader();
    let rotateObj = [];
    const loadLoader = url.endsWith('fbx') ? FBXloader : loader1;
    loadLoader.load(url, function(gltf) {
      const loadscene = gltf.scene || gltf;

      loadscene.scale.set(1, 1, 1);

      let group = new THREE.Group();
      group.add(loadscene);

      let bbox = new THREE.Box3().setFromObject(group);
      // console.log(bbox,'bbox---');
      let mdlen = bbox.max.x - bbox.min.x; //边界的最小坐标值 边界的最大坐标值
      let mdhei = bbox.max.y - bbox.min.y;
      let mdwid = bbox.max.z - bbox.min.z;
      group.position.set(0, 0, 0);
      // console.log(camera,'相机的信息',group,'组的信息');
      let dist = Math.abs(camera.position.z - group.position.z - (mdwid / 2));
      //console.log('dist值为:' + dist );
      let vFov = camera.fov * Math.PI / 180; //弧度=角度*Math.PI/180
      //console.log('vFov值为:' + vFov );
      let vheight = 2 * Math.tan(vFov * 0.5) * dist;
      //console.log('vheight值为:' + vheight );
      let fraction = mdhei / vheight;
      // console.log('fraction值为:' + fraction );
      let finalHeight = height * fraction;
      //console.log('finalHeight值为:' + finalHeight);
      let finalWidth = (finalHeight * mdlen) / mdhei;
      //console.log('finalWidth值为:' + finalWidth );                

      let value1 = width / finalWidth;
      // console.log('value1缩放比例值为:' + value1);
      let value2 = height / finalHeight;
      // console.log('value2缩放比例值为:' + value2);

      if (value1 >= value2) {
        group.scale.set(value2, value2, value2);
      } else {
        group.scale.set(value1 / 2, value1 / 2, value1 / 2);
        // group.scale.set(value1,value1,value1);
      }
      let bbox2 = new THREE.Box3().setFromObject(group)
      // console.log(bbox2,'bbox2');
      let mdlen2 = bbox2.max.x - bbox2.min.x;
      let mdhei2 = bbox2.max.y - bbox2.min.y;
      let mdwid2 = bbox2.max.z - bbox2.min.z;
      group.position.set(-(bbox2.max.x + bbox2.min.x) / 2,
        -(bbox2.max.y + bbox2.min.y) / 2,
        -(bbox2.max.z + bbox2.min.z) / 2);
      document.getElementById("threeView").click(); //去掉加载效果
      scene.add(group);
      // let boxhelper = new THREE.BoxHelper(group,0xbe1915); //辅助线外面红色框
      // scene.add(boxhelper);  
    })
  }
  const animate = () => {
    requestAnimationFrame(animate);
    orbitcontrols.update(); //自动旋转
    renderer.render(scene, camera);
  }
  setTimeout(() => {
    init();
    animate();
    loadModel();
  }, 100)
</script>

上面写法并不优雅, 只是临时作为一个demo可以参考.

注意: 需要自己手动下载three, 在npm中npm i three即可, 同时注意script中的属性

模型链接:百度网盘 请输入提取码

提取码: zsbn文章来源地址https://www.toymoban.com/news/detail-531497.html

到了这里,关于uniapp vue3中使用threejs渲染3D模型的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • THREEJS 在 uni-app 中使用(微信小程序)

    threejs 主要是用来开发web端的3D世界,源生包无法适配 微信小程序(会报 document.createElementNS 的错),需要使用 github 上经过大佬改写的 threejs 包。 将源码下载到本地后,找到 将 以上三个文件 复制到自己的 uni-app 项目中 (任意路径下,这里我放在了自己的 utils 下,好像一般

    2024年02月07日
    浏览(55)
  • 小程序-uni-app:uni-app-base项目基础配置及使用/uni-app+vue3+ts+vite+vscode

    目前(20230605)uni-app最新版本(3.8.4.20230531) 一、官网文档 微信开放文档 uni-app官网 二、创建项目 项目目标:vue3+ts+vite+vscode 创建以 typescript 开发的工程(如命令行创建失败,请直接访问 gitee 下载模板) npx degit dcloudio/uni-preset-vue#vite-ts uniapp-base ​ 本文创建成功 ​ 为了验

    2024年02月15日
    浏览(89)
  • 小程序-uni-app:uni-app-base项目基础配置及使用 / uni-app+vue3+ts+vite+vscode

    目前(20230605)uni-app最新版本(3.8.4.20230531) 一、官网文档 微信开放文档 uni-app官网 二、创建项目 项目目标:vue3+ts+vite+vscode 创建以 typescript 开发的工程(如命令行创建失败,请直接访问 gitee 下载模板) npx degit dcloudio/uni-preset-vue#vite-ts uniapp-base ​ 本文创建成功 ​ 为了验

    2024年02月05日
    浏览(481)
  • uniapp系列-超详细教你在uni-app+vue3里通过web-view组件传递信息打开H5页面写入localstorage并解决兼容性

    web-view 是一个 web 浏览器组件,可以用来承载网页的容器,会自动铺满整个页面(nvue 使用需要手动指定宽高)。 点击这里直达官网文档 点击这里下载我的代码demo 本文最下面还有一些 常见或者奇怪问题解决方案 哦~ 之前开发好的H5页面,不想重新开发,想要直接放进项目用

    2024年02月09日
    浏览(54)
  • Vue3集成ThreeJS实现3D效果,threejs+Vite+Vue3+TypeScript 实战课程【一篇文章精通系列】

    这是一个使用Vue3,TypeScript,Vite和Three.js的项目。Vue3是一个流行的JavaScript框架,用于构建用户界面。TypeScript是一种静态类型的编程语言,它是JavaScript的超集,可以编译成纯JavaScript。Vite是一个由Evan You开发的新的前端构建工具,能够提供快速的冷启动和即时热更新。 Three.j

    2024年02月03日
    浏览(49)
  • VUE3+ThreeJs实现3D全景场景,可自由旋转视角

    three.js是一个用于在Web上创建三维图形的JavaScript库。它可以用于创建各种类型的三维场景,包括游戏、虚拟现实、建筑和产品可视化等。three.js提供了许多功能和特性,包括3D渲染、光照、材质、几何形状、动画、交互和相机控制等。使用three.js,开发人员可以轻松地创建复杂

    2024年02月11日
    浏览(48)
  • uniapp使用vue3语法利用uni.navigateTo跳转和接收参数

    官网利用vue3语法写uni.navigateTo跳转接参可能出现接收参数有问题的情况 ,获取上一个页面数据需要进行调整。         uni官网:uni.navigateTo(OBJECT) | uni-app官网 利用onload钩子3函数接收参数

    2024年02月02日
    浏览(40)
  • uni-app使用vue3,在元素或组件实例上添加ref,用this.$refs显示undefined

    项目中引用了一个UI组件库,在表单上添加了`ref`属性,方便提交时验证。触发提交方法时显示不存在这个方法或this.$refs为undefined。 解决方法: 引入`getCurrentInstance`,t得到当前组件实例,然后用`ctx.$refs`代替`this.$refs`。这里的`ctx`相当于全局this。 ------------------ 2023/10/27更新-

    2024年02月07日
    浏览(49)
  • 手写类似于BetterScroll样式的左右联动菜单 uni-app+vue3+ts (使用了script setup语法糖)

     注意:在模拟器用鼠标滚动是不会切换光标的,因为使用的是触摸滑动。【自定义类型贴在最后了】 script 部分如下:  template部分如下: scss样式:  category.d.ts main-arr.d.ts  

    2024年02月05日
    浏览(45)
  • uni-app+vue3会遇到哪些问题

    已经用 uni-app+vue3+ts 开发了一段时间,记录一下日常遇见的问题和解决办法 uni-app 是支持多端,如果你想让你的代码,只在部分平台使用,那么就需要用的它的单端处理语法 //#ifdef 和 //#ifndef 等。 因为有异形手机屏的存在,最顶部有摄像头,最下面有导航条,为了避免界面内

    2024年02月19日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包