Three.js加载360全景图片/视频

news2024/12/1 10:41:39

Three.js加载360全景图片/视频

效果

请添加图片描述

原理

  • 将全景图片/视频作为texture引入到three.js场景中
  • 将贴图与球形网格模型融合,将球模型当做成环境容器使用
  • 处理视频时需要以dom为载体,加载与控制视频动作
  • 每次渲染时更新当前texture,以达到视频播放效果
  • 全景图片加载有球体与正方体两种模式,区别在于是加载单张图片还是多张图片

核心方法

      // 添加VR全景图
      const addVrPicture = async () => {
        // 创建贴图
        const loader = new THREE.TextureLoader();
        const texture = await loader.load('./img/vr.jpg');
        texture.wrapS = THREE.RepeatWrapping;
        texture.repeat.x = -1;
        // 创建球形载体
        const sphereGeometry = new THREE.SphereGeometry(200, 60, 40);
        const sphereMaterial = new THREE.MeshBasicMaterial({ map: texture, side: THREE.BackSide });
        const sphere = new THREE.Mesh(sphereGeometry, sphereMaterial);
        scene.add(sphere);
      };

      // 添加VR全景视频
      const addVrVideo = async () => {
        // 通过Dom引入并控制视频源
        const video = document.createElement('video');
        video.src = './video/vr.mp4';
        video.loop = true;
        video.muted = true;
        video.autoplay = true;
        // 创建视频贴图
        const texture = new THREE.VideoTexture(video);
        texture.minFilter = THREE.LinearFilter;
        // 创建球形载体
        const sphereGeometry = new THREE.SphereGeometry(200, 60, 40);
        const sphereMaterial = new THREE.MeshBasicMaterial({ map: texture, side: THREE.BackSide });
        const sphere = new THREE.Mesh(sphereGeometry, sphereMaterial);
        scene.add(sphere);
        // 添加动画序列
        animationList.push(() => {
          // 更新视频纹理
          // 播放视频
          video.play();
          if (video.readyState === video.HAVE_ENOUGH_DATA) {
            texture.needsUpdate = true;
          }
        });
        // 调整相机视角
        const point = new THREE.Vector3(200, 0, 0);
        camera.lookAt(point);
      };

完整代码

<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      * {
        margin: 0;
        padding: 0;
      }
    </style>
  </head>
  <body>
    <script type="module">
      import * as util from './js/util.js';
      import * as THREE from './node_modules/three/build/three.module.js';
      import { creatWallByPath } from './js/effect.js';

      const scene = util.initScene();
      const stats = util.initStats();
      const camera = util.initCamera(-1, 0, 0);
      const renderer = util.initRender();
      const controls = util.initOrbitControls(camera, renderer);
      util.windowReSize(renderer, camera);
      util.addAxisHelper(scene, 100);
      util.addAmbientLight(scene);
      util.addDirectionalLight(scene);
      // 动画序列,每个渲染周期执行
      const animationList = [];

      // 添加VR全景图
      const addVrPicture = async () => {
        // 创建贴图
        const loader = new THREE.TextureLoader();
        const texture = await loader.load('./img/vr.jpg');
        texture.wrapS = THREE.RepeatWrapping;
        texture.repeat.x = -1;
        // 创建球形载体
        const sphereGeometry = new THREE.SphereGeometry(200, 60, 40);
        const sphereMaterial = new THREE.MeshBasicMaterial({ map: texture, side: THREE.BackSide });
        const sphere = new THREE.Mesh(sphereGeometry, sphereMaterial);
        scene.add(sphere);
      };

      // 添加VR全景视频
      const addVrVideo = async () => {
        // 通过Dom引入并控制视频源
        const video = document.createElement('video');
        video.src = './video/vr.mp4';
        video.loop = true;
        video.muted = true;
        video.autoplay = true;
        // 创建视频贴图
        const texture = new THREE.VideoTexture(video);
        texture.minFilter = THREE.LinearFilter;
        // 创建球形载体
        const sphereGeometry = new THREE.SphereGeometry(200, 60, 40);
        const sphereMaterial = new THREE.MeshBasicMaterial({ map: texture, side: THREE.BackSide });
        const sphere = new THREE.Mesh(sphereGeometry, sphereMaterial);
        scene.add(sphere);
        // 添加动画序列
        animationList.push(() => {
          // 更新视频纹理
          // 播放视频
          video.play();
          if (video.readyState === video.HAVE_ENOUGH_DATA) {
            texture.needsUpdate = true;
          }
        });
        // 调整相机视角
        const point = new THREE.Vector3(200, 0, 0);
        camera.lookAt(point);
      };

      const main = async () => {
        // 添加VR图像
        await addVrPicture();
        // 添加VR视频
        // await addVrVideo();
      };

      // 渲染函数
      const render = () => {
        renderer.render(scene, camera);
        stats.update();
        animationList.forEach((callback) => callback());
        requestAnimationFrame(render);
      };

      window.onload = () => {
        main();
        render();
      };
    </script>
  </body>
</html>

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

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

相关文章

强化学习到底是什么?它是怎么运维的

https://mp.weixin.qq.com/s/LL3HfU2iNlmSqaTX_3J7fQ 强化学习是一种行为学习模型,由算法提供数据分析反馈,引导用户逐步获取最佳结果。 来源丨Towards Data Science 作者丨Jair Ribeiro 编译丨科技行者 强化学习属于机器学习中的一个子集,它使代理能够理解在特定环境中…

TensorFlow入门(四、数据流向机制)

session与"图"工作过程中存在的两种数据的流向机制,即:注入机制和取回机制 注入机制(feed):即通过占位符向模式中传入数据 取回机制(fetch):指在执行计算图时&#xff0c;可以同时获取多个操作节点的计算结果 实例代码如下: import tensorflow.compat.v1 as tftf…

【Java】建筑工地智慧管理系统源码

智慧工地系统运用物联网信息技术&#xff0c;致力于推动建筑工程行业的建设发展&#xff0c;做到全自动、信息化&#xff0c;智能化的全方位智慧工地&#xff0c;实现工程施工可视化智能管理以提高工程管理信息化水平。 智慧工地平台拥有一整套完善的智慧工地解决方案&#xff…

C语言入门Day_27 开发环境

前言&#xff1a; 在线编译环境涉及到联网&#xff0c;如果在没有网的情况下&#xff0c;我们就不能写代码了&#xff0c;这一章节&#xff0c;我们将会给大家介绍一下如何搭建一个本地的C语言编译环境。 如果想要设置 C 语言环境&#xff0c;需要确保电脑上有以下两款可用的…

Hive【Hive(三)查询语句】

前言 今天是中秋节&#xff0c;早上七点就醒了&#xff0c;干啥呢&#xff0c;大一开学后空教室紧缺&#xff0c;还不趁着假期来学校等啥呢。顺便偷偷许个愿吧&#xff0c;希望在明年的这个时候&#xff0c;秋招不知道赶不赶得上&#xff0c;我希望拿几个国奖&#xff0c;蓝桥杯…

基于微信小程序的宠物寄养平台小程序设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言系统主要功能&#xff1a;具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序&#xff08;小蔡coding&#xff09;有保障的售后福利 代码参考源码获取 前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计…

Spark SQL案例【电商购买数据分析】

数据说明 Spark 数据分析 &#xff08;Scala&#xff09; import org.apache.spark.rdd.RDD import org.apache.spark.sql.{DataFrame, SparkSession} import org.apache.spark.{SparkConf, SparkContext}import java.io.{File, PrintWriter}object Taobao {case class Info(u…

26270-2010 数字电视接收设备标准测试信号

声明 本文是学习GB-T 26270-2010 数字电视接收设备标准测试信号. 而整理的学习笔记,分享出来希望更多人受益,如果存在侵权请及时联系我们 1 范围 本标准规定了数字电视接收设备测试用的标准测试信号。 本标准适用于我国地面、有线和卫星数字电视广播接收设备测试。数字电视…

【小余送书第二期】《MLOps工程实践:工具、技术与企业级应用》参与活动,即有机会中奖哦!!!祝各位铁铁们双节快乐!

目录 1、背景介绍 2、内容简介 3、读者对象 4、专家推荐 5、书籍目录 目  录 作者简介 前言 第1章 全面了解MLOps1 1.1 人工智能的趋势和现状 1 1.1.1 趋势1&#xff1a;人工智能在企业中加速落地&#xff0c;彰显更多业务价值 1 1.1.2 趋势2&#xff1a;人…

每日一博 - 闲聊 Java 中的中断

文章目录 概述常见的中断问题中断一个处于运行状态的线程中断一个正在 sleep 的线程中断一个由于获取 ReentrantLock 锁而被阻塞的线程 如何正确地使用线程的中断标识JDK 的线程池 ThreadPoolExecutor 内部是如何运用中断实现功能的小结 概述 在 Java 中&#xff0c;中断是一种…

提升工作效率!如何巧用 Ansible 实现自动化运维?

Ansible 是一种开源的自动化运维工具&#xff0c;它基于 YAML 语言编写 playbook&#xff0c;可以用来自动化服务器的配置、部署和管理。 Ansible 使用 SSH 协议进行通信&#xff0c;可以在大量服务器上进行批量操作&#xff0c;无需在目标服务器上安装任何客户端软件。它支持…

ip的标准分类---分类的Ip

分类的 IP 即将 IP 地址划分为若干个固定类&#xff0c;每一类地址都由两个固定长度的字段组成。 其中第一个字段是网络号&#xff08;net-id&#xff09;&#xff0c;它标志主机或路由器所连接的网络。一个网络号在整个因特网内必须是唯一的。 第二个字段是主机号&#xf…

Microsoft Office无法重装报错30015-44(3) 0-2031(17004)

1.问题描述 由于迁移文件夹导致Microsoft office软件无法使用&#xff0c;于是准备卸载重装&#xff0c;但是点击OfficeSetup.exe出现报错30015-44(3) 关闭后出现以下报错0-2031(17004) 2. 尝试的解决方式 重启后仍然无法解决问题 2.1 参考官网解决办法 手动从控制面板&…

Flutter笔记 - ListTile组件及其应用

Flutter笔记 ListTile组件及其应用 作者&#xff1a;李俊才 &#xff08;jcLee95&#xff09;&#xff1a;https://blog.csdn.net/qq_28550263 邮箱 &#xff1a;291148484163.com 本文地址&#xff1a;https://blog.csdn.net/qq_28550263/article/details/133411883 目 录 1. …

王道考研计算机网络——传输层

一、传输层概述 复用&#xff1a;发送方不同的应用进程都可以使用同一个传输层的协议来传送数据 分用&#xff1a;接收方的传输层在去除报文段的首部之后能把数据交给正确的应用进程 熟知端口号就是知名端口号0-1023 客户端使用的端口号是动态变化的&#xff0c;不是唯一确定…

禾观科技采用亚马逊云科技的数据湖,实现数据化驱动运营的核心

如今&#xff0c;随着本土业务发展渐趋成熟&#xff0c;越来越多的中国企业开始依托跨境电商实现产品出口外销&#xff0c;大力拓展海外布局。在这一背景下&#xff0c;众多潜在机遇涌现&#xff0c;成为跨境电商“蓝海”的必争之地。 杭州禾观科技有限公司是面向全球新兴快时尚…

【JavaEE基础学习打卡08】JSP之初次认识say hello!

目录 前言一、JSP技术初识1.动态页面2.JSP是什么3.JSP特点有哪些 二、JSP运行环境配置1.JDK安装2.Tomcat安装 三、编写JSP1.我的第一个JSP2.JSP执行过程3.在IDEA中开发JSP 总结 前言 &#x1f4dc; 本系列教程适用于JavaWeb初学者、爱好者&#xff0c;小白白。我们的天赋并不高…

排序:最佳归并树(优化外部排序中对磁盘的读写次数)

1.归并树的性质 每个初始归并段对应一个叶子结点&#xff0c;把归并段的块数作为叶子的权值归并树的WPL树中所有叶结点的带权路径长度之和归并过程中的磁盘I/O次数归并树的WPL*2 如下图&#xff1a; 每个初始归并段看作一个叶子结点&#xff0c;归并段的长度作为结点权值&a…

源码编译安装zstd

目录 1 下载源码https://github.com/facebook/zstd 2 解压 3 在解压后的目录里输入make 4 sudo make install 安装完毕 5 输入whereis zstd 检查安装结果 1 下载源码https://github.com/facebook/zstd 2 解压 3 在解压后的目录里输入make 4 sudo make install 安装完毕…

利用抽象工厂模式提升游戏开发的精度与灵活性

引言 大家好&#xff0c;我是亿元程序员&#xff0c;一位有着8年游戏行业经验的主程。 本系列是《和8年游戏主程一起学习设计模式》&#xff0c;让糟糕的代码在潜移默化中升华&#xff0c;欢迎大家关注分享收藏订阅。 在开发过程中&#xff0c;如何有效地管理各种游戏对象并…