Three.js(学习)

2023-10-26

在vue项目中使用Three.js的流程

1.首先利用npm安装Q three.js,具体操作代码如下
   npm install three
2.接下来利用npm安装轨道控件插件:
  npm install three-orbit-controls

3.接下来安装加载.obj和.mtl文件的插件:
  npm i --save three-obj-mtl-loader


4.安装渲染器插件:
 npm i --save three-css2drender

安装好以后,在页面中引入three.is并使用,在所调用页面引入的代码为:
1 import * as Three from 'three

要记得引入three.js

  1. 先创建场景       
  2. 创建相机
  3. 设置相机位置
  4. 添加物体  创建几何体
  5. 根据几何体和材质创建物体
  6. 将几何体添加到场景中
  7. 初始化渲染器
  8. 设置渲染器尺寸大小
  9. 将webgl渲染的canvas内容添加到body
  10. 使用渲染器,通过相机将场景渲染进来

 直接上代码:

      //创建场景
      const scene = new THREE.Scene();
      //创建相机
      const camera = new THREE.PerspectiveCamera(75,homebox.clientWidth/homebox.clientHeight,0.1,1000);
      //改变相机的初始位置
      camera.position.set(0,0,10);
      //在相机添加到场景
      scene.add(camera);
      //添加物体 创建几何体
      const cubeGeomtry = new THREE.BoxGeometry(1,1,1);//添加几何体
      const cubeMaterial = new THREE.MeshBasicMaterial({color:0xffbb00})//添加材质
      //根据几何体和材质创建物体 
      const cube = new THREE.Mesh(cubeGeomtry,cubeMaterial);
      //将几何体添加到场景
      scene.add(cube);
      //初始化渲染器
      const renderer = new THREE.WebGLRenderer();
      //设置渲染器的尺寸
      renderer.setSize(window.innerWidth,window.innerHeight);
      //将webgl渲染的canvas内容添加到页面容器中
      homebox.appendChild(renderer.domElement);
      //使用渲染器,通过相机将场景渲染进来
      renderer.render(scene,camera);

 以上代码,只是简单的在浏览器渲染出一个立方体(静止)想要它可以随鼠标拖动,还需进行以下操作:

//导入轨道控制器
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls"; 

//创建轨道控制器
     var controls=new OrbitControls(camera,renderer.domElement);

    // 添加一个动画函数
      function Aboutanimate() {
        requestAnimationFrame(Aboutanimate);//请求动画帧  每帧执行一次动画函数
        renderer.render(scene,camera);//渲染
      }

为了方便我们观察物体所在的位置,还需进行以下操作:

      //添加坐标轴辅助器
      const axesHelper = new THREE.AxesHelper(5)//参数代表坐标轴长度
      scene.add(axesHelper)//把坐标轴辅助器添加到场景中

现在我们就可以看到一个立方体,如果只是这样还远远满足不了我们的需求,所以我们要让立方体动起来,下面代码就可以实现:

import gsap from 'gsap';//导入动画库   要记得npm安装一下  npm install gsap
//gsap是补间动画库
//设置补间动画
      let animation= gsap.to(cube.position,{x:5,duration:5,ease:"powerl.inOut",
      repeat:5,  //设置重复次数  无限次重复设置为-1
      yoyo:true, //设置往返运动
      delay:2,   // delay 设置2秒延迟
      onComplete:()=>{
        console.log('动画完成');
      },
      onStart:()=>{
        console.log('动画开始');
      }
    })
      gsap.to(cube.rotation,{x:2*Math.PI,duration:5,ease:"powerl.inOut",repeat:5,yoyo:true})

现在我们就可以看到立方体动起来了,为了方便我们开发调试,我们需要一个可以实时控制的面板,可以用下面代码实现:

 //导入dat.gui
import * as dat from 'dat.gui'  
//移动X轴坐标 
      const gui = new dat.GUI();
      gui.add(cube.position,"x").min(0).max(5).step(0.01).name('移动X轴坐标').onChange((value)=>{
        console.log('值被修改:',value);
      }).onFinishChange((valur)=>{
        console.log("完全停下来");
      });

       //移动Y轴坐标  
      gui.add(cube.position,"y").min(0).max(5).step(0.01).name('移动Y轴坐标').onChange((value)=>{
        console.log('值被修改:',value);
      }).onFinishChange((valur)=>{
        console.log("完全停下来");
      });
      
//移动Z轴坐标  
       gui.add(cube.position,"z").min(0).max(5).step(0.01).name('移动Z轴坐标').onChange((value)=>{
        console.log('值被修改:',value);
      }).onFinishChange((valur)=>{
        console.log("完全停下来");
      });
//控制旋转
      gui.add(cube.rotation,'x').min(0).max(2*Math.PI).step(0.01).name('转动X轴')
      gui.add(cube.rotation,'y').min(0).max(2*Math.PI).step(0.01).name('转动Y轴')
      gui.add(cube.rotation,'z').min(0).max(2*Math.PI).step(0.01).name('转动Z轴')
 
//改变物体颜色
      const params = {
        color:'#ffff00',
        fn:()=>{
          //让立方体运动起来
          gsap.to(cube.position,{x:5,duration:5,yoyo:true,repeat:-1})
        }
      }
      gui.addColor(params,"color").name('物体颜色').onChange((value)=>{
        console.log("值被改变:",value);
        cube.material.color.set(value)
      })
      //设置选项框
      gui.add(cube,'visible').name('是否显示')
    
      
//设置文件夹
      var folder= gui.addFolder('设置立方体')
      folder.add(cube.material,'wireframe')
      //设置按钮点击触发某个事件
      folder.add(params,'fn').name('点击立方体运动')

为了实现响应式,这里添加了以下代码:

 //调用js接口
        //双击控制屏幕进入全屏,退出全屏
        const fullScreenElement = document.fullscreenElement;
        if (!fullScreenElement) {
          renderer.domElement.requestFullscreen()
        } else {
          document.exitFullscreen()
          
        }
        
      })
      //监听画面变化,更新渲染画面
      window.addEventListener('resize',()=>{
        console.log('画面变化了');
        camera.aspect = homebox.clientWidth/homebox.clientHeight;//更新摄像头
        camera.updateProjectionMatrix();//更新摄像机的投影矩阵
        renderer.setSize(window.innerWidth,window.innerHeight);//更新渲染器
        
        renderer.setPixelRatio(homebox.devicePixelRatio);//设置渲染器的像素比
      })

下面是完整代码:

<template>
  <div id='Home'></div>
</template>

<script>
//引入three.js
import * as THREE from 'three'; 
//导入轨道控制器
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls"; 
//导入动画库
import gsap from 'gsap';
//导入dat.gui
import * as dat from 'dat.gui';  
export default {
  data() {
    return {
      
    }
  },
  mounted() {
   this.init()
   
    
    
  },
  methods: {
    init(){
      //获取dom元素
      let homebox = document.getElementById('Home');

      //创建场景
      const scene = new THREE.Scene();

      //创建相机
      const camera = new THREE.PerspectiveCamera(75,homebox.clientWidth/homebox.clientHeight,0.1,1000);

      //改变相机的初始位置
      camera.position.set(0,0,10);

      //在相机添加到场景
      scene.add(camera);

      //添加物体 创建几何体
      const cubeGeomtry = new THREE.BoxGeometry(1,1,1);//添加几何体
      const cubeMaterial = new THREE.MeshBasicMaterial({color:0xffbb00})//添加材质

      //根据几何体和材质创建物体 
      const cube = new THREE.Mesh(cubeGeomtry,cubeMaterial);

      //将几何体添加到场景
      scene.add(cube);

      //移动X轴坐标 
      const gui = new dat.GUI();
      gui.add(cube.position,"x").min(0).max(5).step(0.01).name('移动X轴坐标').onChange((value)=>{
        console.log('值被修改:',value);
      }).onFinishChange((valur)=>{
        console.log("完全停下来");
      });

       //移动Y轴坐标  
      gui.add(cube.position,"y").min(0).max(5).step(0.01).name('移动Y轴坐标').onChange((value)=>{
        console.log('值被修改:',value);
      }).onFinishChange((valur)=>{
        console.log("完全停下来");
      });
      

       //移动Z轴坐标  
       gui.add(cube.position,"z").min(0).max(5).step(0.01).name('移动Z轴坐标').onChange((value)=>{
        console.log('值被修改:',value);
      }).onFinishChange((valur)=>{
        console.log("完全停下来");
      });


      //控制旋转
      gui.add(cube.rotation,'x').min(0).max(2*Math.PI).step(0.01).name('转动X轴')
      gui.add(cube.rotation,'y').min(0).max(2*Math.PI).step(0.01).name('转动Y轴')
      gui.add(cube.rotation,'z').min(0).max(2*Math.PI).step(0.01).name('转动Z轴')
 

      //改变物体颜色
      const params = {
        color:'#ffff00',
        fn:()=>{
          //让立方体运动起来
          gsap.to(cube.position,{x:5,duration:5,yoyo:true,repeat:-1})
        }
      }
      gui.addColor(params,"color").name('物体颜色').onChange((value)=>{
        console.log("值被改变:",value);
        cube.material.color.set(value)
      })
      //设置选项框
      gui.add(cube,'visible').name('是否显示')

      
      //设置文件夹
      var folder= gui.addFolder('设置立方体')
      folder.add(cube.material,'wireframe')
      //设置按钮点击触发某个事件
      folder.add(params,'fn').name('点击立方体运动')

      //初始化渲染器
      const renderer = new THREE.WebGLRenderer();

      //设置渲染器的尺寸
      renderer.setSize(window.innerWidth,window.innerHeight);

      //将webgl渲染的canvas内容添加到页面容器中
      homebox.appendChild(renderer.domElement);

      //使用渲染器,通过相机将场景渲染进来
      // renderer.render(scene,camera);
      Aboutanimate()

      //创建轨道控制器
      var controls=new OrbitControls(camera,renderer.domElement);

      //添加坐标轴辅助器
       const axesHelper = new THREE.AxesHelper(5)//参数代表坐标轴长度
       scene.add(axesHelper)//把坐标轴辅助器添加到场景中

      
      //这里可以不要 
       //设置补间动画
    //  let animation= gsap.to(cube.position,{x:5,duration:5,ease:"powerl.inOut",
    //  repeat:5,  //设置重复次数  无限次重复设置为-1
    //  yoyo:true, //设置往返运动
    //  delay:2,   // delay 设置2秒延迟
    //  onComplete:()=>{
    //    console.log('动画完成');
    //  },
    //  onStart:()=>{
    //    console.log('动画开始');
    //  }
    //  })
    //    gsap.to(cube.rotation,{x:2*Math.PI,duration:5,ease:"powerl.inOut",repeat:5,yoyo:true})




     //双击触发事件  监听鼠标双击
     window.addEventListener("dblclick",()=>{
        // console.log(animation);
        // if (animation.isActive()) {
        //   //暂停动画
        //   animation.pause()
        // } else {
        //   //恢复动画
        //   animation.resume()
        // }

        //调用js接口
        //双击控制屏幕进入全屏,退出全屏
        const fullScreenElement = document.fullscreenElement;
        if (!fullScreenElement) {
          renderer.domElement.requestFullscreen()
        } else {
          document.exitFullscreen()
          
        }
        
      })
      //监听画面变化,更新渲染画面
      window.addEventListener('resize',()=>{
        console.log('画面变化了');
        camera.aspect = homebox.clientWidth/homebox.clientHeight;//更新摄像头
        camera.updateProjectionMatrix();//更新摄像机的投影矩阵
        renderer.setSize(window.innerWidth,window.innerHeight);//更新渲染器
        
        renderer.setPixelRatio(homebox.devicePixelRatio);//设置渲染器的像素比
      })
      
      // 动画函数
      function Aboutanimate() {
        requestAnimationFrame(Aboutanimate);//请求动画帧  每帧执行一次动画函数
        renderer.render(scene,camera);//渲染
      
       }

    }
  },
}
</script>

<style scoped lang='scss'>
#Home {
  width: 100vh;
  height: 100vh;
}
</style>

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

Three.js(学习) 的相关文章

  • AFrame:重新调整元素的父级,保持其世界位置、旋转

    我正在尝试重新设置元素 实体 的父级 保持其在场景中的位置 旋转 以及如果可能的话 大小 例如比例 理想情况下 我希望有一个组件 例如 reparent 当在实体上设置时 将其 移动 到指定的父级 从而将实体的外观保留在场景中 例如 对于下
  • WebGL/OpenGL:根据设备方向旋转相机

    我有一个 Web 应用程序 我试图在 3D 空间中显示地图图像图块的平面 我希望无论设备如何旋转 平面始终保持水平 最终效果类似于这个航海罗盘演示 http people opera com richt release demos orie
  • 三个 Js Object3D 按钮组检测单个对象点击,同时鼠标移动导致 Object3D 按钮组 Zoomi

    我正在尝试检测 Object3D 立方体组中的立方体单击 我已查看并尝试合并以下位置的示例和教程 http mrdoob github com Three js examples webgl interactive cubes html h
  • 在 Three.js 中使用 CanvasRenderer 绘制线条比 WebGLRenderer 更平滑

    我一直遇到一个问题 即 Three js 的 CanvasRenderer 渲染线比 WebGLRenderer 平滑得多 WebGLRenderer 似乎没有应用抗锯齿功能 当我从 中获取 Three js 画布 线条 随机示例时http
  • 如何?从 kinect 数据为 Three.js 示例 webgl_kinect 创建 webm 视频

    http mrdoob github com Three js examples webgl kinect html http mrdoob github com three js examples webgl kinect html 如何
  • Three.js - 如何反序列化geometry.toJSON()? (geometry.fromJSON 在哪里?)

    我正在尝试卸载一些Geometry加载并处理到网络工作者中 要将其发送回主线程 Geometry实例需要序列化 看起来Geometry prototype toJSON 正是针对这种类型的事情 但我不知道如何将该对象转回Geometry主线
  • Threejs 变换矩阵排序

    我想知道 Threejs 如何对多个矩阵进行排序 例如 var mesh new THREE Mesh geometry material mesh position set 0 20 0 T transform matrix mesh r
  • Three.js 的外观似乎被翻转了

    我这里有一个演示 测试场地 http www myuplay com game test html or Backup http direct myuplay com game test html 由于某种原因 即使鼠标矢量是正确的 我的对
  • Three.js - 从点缩放圆柱体

    是否可以从特定点开始增加 Y 轴上圆柱体的比例 与圆柱体从其原点向上和向下生长到新比例不同 它只是像条形图一样从顶部向上 向下生长 当前代码 function animate render cylinder scale y 0 1 requ
  • 使用 OrbitControls 时锁定 x 轴旋转 - Three.js

    使用 OrbitControls 时锁定 x 轴旋转是否可行 目前我有一个挂在绳子上的圣诞星的对象模型 我希望它仅水平旋转 对于您的 OrbitControls 实例集 controls minPolarAngle Math PI 2 co
  • Three.js ShaderMaterial 灯光问题

    你好 这是我的代码的一部分 地球仪 function createGlobe var normalMap THREE ImageUtils loadTexture images earth normal 2048 jpg var surfa
  • Three.jsmaterialLoader不加载嵌入的纹理图像

    我使用 Material toJSON 提供的方法导出 Three js 材质 结果如下 metadata version 4 5 type Material generator Material toJSON uuid 8E6F9A32
  • Three.js 通过加载模型上的材质名称为材质添加边框

    是否可以在材料周围添加边框 如图所示 我可以通过以下代码设置材质颜色 object traverse function child if child instanceof THREE Mesh child material color se
  • 绕局部轴旋转

    我正在尝试实现一个对象 围绕一个位置 POI 兴趣点 飞行并面向它 当您按 WASD 时 您可以更改 POI 的旋转 A 和 D gt 更改 y 轴 W 和 S 更改 x 轴 正如您在演示中看到的 http jsbin com yodusu
  • 如何沿着简单的路径移动相机

    如何沿着简单的路径 由顶点 点数组创建 移动相机 我需要自动移动它 而不是像第一人称射击游戏那样通过键盘 鼠标事件来移动它 找了这个例子 http trijs org examples webgl geometry extrude spli
  • 星系模拟:更改点的颜色并在鼠标悬停时显示文本

    我正在尝试创建模拟 https riteshsingh github io galaxies 4673 个最近星系的位置 星系是点 我想为鼠标悬停时的点着色并加载星系的名称 我花了很多天试图实现它 我可以更改颜色以及进行基本的光线投射 但是
  • 在 React 中渲染 Three.js 元素?

    我正在尝试制作一个渲染 Three js 场景的 React 组件 但是 每当我尝试安装组件而不是看到正在渲染的任何类型的场景时 我只看到文本 object HTMLCanvasElement 正在显示 这是我的组件 import Reac
  • 可点击的精灵标签?

    我一直在玩精灵文本标签 更具体地说是这个例子 http stemkoski github io Three js Sprite Text Labels html http stemkoski github io Three js Sprit
  • 调试 Three.js 中的低 FPS

    我正在处理 Three js WebGL 场景 当我缩小时 我注意到 60 FPS 以便所有观察结果 约 20 000 个三角形 都在视图中 但当我放大时 FPS 非常低 因此只有一个小三角形的子集在视野中 我想弄清楚是什么导致了这种差异
  • 一次性渲染阴影

    考虑到阴影投射的成本 我想知道对于动态定位的静态对象 例如 程序城市 是否有一个功能或可能 实验性的方法可以在 Three js 中仅渲染一次阴影贴图 甚至在 webgl 中 因此 结果可以在静态对象的下一帧中免费使用 仅当物体移动时才会进

随机推荐

  • Arduino pro micro开发板的程序烧录问题

    Arduino pro micro是我大二的时候买的一个开发板 当时是玩Arduino开发板之后 尝试做一个小东西 但是买回来后 不知道程序怎么下载 多种尝试也没有成功 时隔多年 在家收拾东西翻出来后 再试了一下 发现我当时想多了 没好好地
  • IDEA教程之Activiti插件

    本文作者 Spring ZYL 文章来源 人生就是一个不断学习的过程 码农StayUp CSDN博客 SpringBoot全家桶 Java数据结构与算法分析 设计模式领域博主 版权声明 本文版权归作者所有 转载请注明出处 一 安装Activ
  • 《软件测试》第十四章 网站测试

    软件测试 第十四章 网站测试 14 0 前言 14 1 网页基础 14 2 黑盒测试 14 2 1 文本 14 2 2 超级链接 14 2 3 图片 14 2 4 表单 14 2 5 对象和其他各种简单的功能 14 3 灰盒测试 14 4
  • QQ和MSN 在线代码

    QQ在线聊天代码 a href img src images qq交谈 bmp alt qq交谈 width 68 height 29 border 0 a MSN在线聊天代码 a href target blank img src ima
  • Callable 和 Future

    Callable 和 Future 是 Java 并发编程中用于处理多线程任务的两个关键接口 它们通常与线程池一起使用 以实现异步任务执行和获取结果的功能 Callable Callable 是一个泛型接口 它定义了一个带有返回值的任务 与
  • 多线程爬虫的实现----threading库的使用

    1 作爬虫的时候为了提升抓取的速度 这个时候就需要开启多个线程同时抓取数据 今天就分享一下如何使用Python中的threading库实现多线程抓取数据 from shop import ShopSpider import threadin
  • 微服务框架相关 OpenFeign 源码

    目录 一 基础 二 初始化注册 三 FeignClient 自动配置 四 FeignClient 创建 五 网络请求的发出 六 负载均衡 SpringCloud Loadbalancer 一 基础 使用 OpenFeign 流程 项目中引入
  • 2如何识别操作系统_信创产业成为风口,如何“迁移”值得研究(二)

    在上一讲 信创产业成为风口 如何 迁移 值得研究 中 我们分析了什么是 信创 以及数据迁移在信创过程中的重要意义及其基本要求 本次文章中我们将继续分析 信创实践过程中数据迁移的难点及其解决之道 1难点1 迁移场景复杂 在信创实践过程中 随着
  • html搜索栏热搜效果,CSS3实战开发:百度新闻热搜词特效实战开发_html/css_WEB-ITnose...

    各位网友 今天这篇文章 我将手把手带领大家开发百度新闻首页的 新闻热搜词 特效 在这个特效中应用的知识点都很基础 如果你对这些还不清楚 可以关注我以前写的详细教程 今天讲这个案例 也是希望告诉大家 在开发一个特效的时候 请不要将问题复杂化
  • valn的基础配置

    vlan作业 1 交换机进行vlan配置 lsw1 lsw2 2 进行单臂路由的配置 3 DHCP配置 地址池的配置 端口启动
  • LR-ASPP论文

    论文地址 https arxiv org abs 1905 02244 摘要 我们提出了基于互补搜索技术的组合以及一个新颖的架构设计的下一代移动网络 MobileNetV3通过结合NetAdapt算法补充的硬件网络架构搜索 NAS 调整到移
  • 配置JAVA环境变量

    一 自行安装JDK 位置默认C盘 JDK全称是Java Development Kit 是整个Java的核心 包括了Java运行环境 Java工具和Java基础类库 JDK 是整个Java的核心 包括了Java运行环境 Java工具和Jav
  • 一文读懂 QUIC 协议:更快、更稳、更高效的网络通信

    作者 李龙彦 来源 infoQ 你是否也有这样的困扰 打开 APP 巨耗时 刷剧一直在缓冲 追热搜打不开页面 信号稍微差点就直接加载失败 如果有一个协议能让你的上网速度 在不需要任何修改的情况下就能提升 20 特别是网络差的环境下能够提升
  • 万得Wind量化与东方财富Choice量化接口使用

    接口需要付费 这里接口的付费和配置就不展开了 wind相对容易配置 直接用软件就可以点击并配置 东财请参考 Mac使用Python接入东方财富量化接口Choice 调试与获取数据 但有一点需要注意 wind使用量化接口的时候wind终端需要
  • 王炸功能ChatGPT 联网插件功能放开,视频文章一键变思维导图

    就在上周5月13日 Open AI 发文称 我们将在下周向所有ChatGPT Plus 用户开放联网功能和众多插件 这意味着什么 首先联网功能将使得ChatGPT不再局限于回答2021年9月之前的信息 能直接联网查询最新消息 而插件功能就可
  • BIOS启动过程详解

    BIOS 工作原理 最近几天在看 UNIX 操作系统设计 突然想到计算机是如何启动的呢 那就得从 BIOS 说起 其实这个冬冬早已是 n 多人写过的了 今天就以自己的理解来写写 权当一个学习笔记 一 预备知识 很多人将 BIOS 与 CMO
  • 19.3剪裁

    1 在固定管线中 裁剪是在世界坐标系中 2 在可编程管线中 裁剪是在规格化坐标系中 步骤 1 按照法向量和空间点定义裁剪平面 并归一化 2 根据世界观察投影变换矩阵相乘 求逆转置 即为需要的变换矩阵 3 变换矩阵与裁剪平面变换后就是需要的裁
  • numpy模块(2)

    1 利用布尔值来取元素 import numpy as np mask np array 1 0 1 dtype bool 1表示取对应的元素 0表示不取 arr np array 1 2 3 4 5 6 7 8 9 print arr m
  • Hadoop学习心得---二

    大数据运算解决方案MapReduce Hadoop的分布式计算模型MapReduce 最早是Google提出的 主要用于搜索领域 解决海量数据的计算问题 MapReduce有两个阶段组成 Map和Reduce 用户只需实现map 和redu
  • Three.js(学习)

    在vue项目中使用Three js的流程 1 首先利用npm安装Q three js 具体操作代码如下 npm install three 2 接下来利用npm安装轨道控件插件 npm install three orbit control