Cesium集成WebXR_连接VR设备

article/2025/8/18 7:04:43

Cesium集成WebXR

文章目录

  • Cesium集成WebXR
    • 1. 需求
    • 2. 技术基础
      • 2.1 WebGL
      • 2.2 WebXR
      • 2.3 其他
    • 3. 示例代码
    • 4. 效果图
    • 5. 参考链接

1. 需求

通过WebXR接口,将浏览器端连接到VR头盔,实现在VR头盔中浏览Cesium场景,并可将头盔旋转的操作同步映射为场景视角的变换,实现沉浸式体验。

2. 技术基础

2.1 WebGL

需要了解一些关于WebGL的基础知识,通过以下几个链接可快速了解:

  • WebGL 入门
  • WebGL 着色器获取js数据
  • 【零基础学WebGL】绘制矩形
  • 【零基础学WebGL】绘制图片

2.2 WebXR

关于WebXR可参见MDN上有关介绍Fundamentals of WebXR。

WebXR, with the WebXR Device API at its core, provides the functionality needed to bring both augmented and virtual reality (AR and VR) to the web.

WebXR is an API for web content and apps to use to interface with mixed reality hardware such as VR headsets and glasses with integrated augmented reality features. This includes both managing the process of rendering the views needed to simulate the 3D experience and the ability to sense the movement of the headset (or other motion-sensing gear) and provide the needed data to update the imagery shown to the user.

另外,MDN提供了一个例子可以帮助快速上手,该示例未依赖其他三维框架(如three.js),使用纯原生WebGL接口,相关介绍见Movement, orientation, and motion: A WebXR example,在线运行示例见WebXR: Example with rotating object and user movement(可浏览源代码,并下载到本地运行调试)。

2.3 其他

另外需要了解一些矩阵变换(平移、缩放、旋转)知识,可参考以下链接:

  • Matrix math for the web - MDN
  • 旋转变换(一)旋转矩阵

3. 示例代码

注:未接入实体VR设备,使用浏览器插件 WebXR API Emulator 模拟。

<!DOCTYPE html>
<html lang="en"><head><!-- Use correct character set. --><meta charset="utf-8" /><!-- Tell IE to use the latest, best version. --><meta http-equiv="X-UA-Compatible" content="IE=edge" /><!-- Make the application on mobile take up the full browser screen and disable user scaling. --><meta name="viewport"content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no" /><title>Hello World!</title><script src="../Build/Cesium/Cesium.js"></script><style>@import url(../Build/Cesium/Widgets/widgets.css);html,body,#cesiumContainer {width: 100%;height: 100%;margin: 0;padding: 0;overflow: hidden;}.cesium-viewer-vrContainer {z-index: 10000;}</style>
</head><body><div id="cesiumContainer"></div><script>// Cesium.Ion.defaultAccessToken = 'your_token';var viewer = new Cesium.Viewer("cesiumContainer", {vrButton: true});let gl, refSpace, xrSession, animationFrameRequestID;let originalDirection; // 进入VR模式前的场景相机信息// vrButton设置监听事件,进入vr模式后检测vr设备viewer.vrButton.viewModel.command.afterExecute.addEventListener(() => {// 刚进入VR模式if (viewer.vrButton.viewModel.isVRMode) {setTimeout(() => {// 检查当前环境if (navigator.xr) {// 检查是否支持 immersive-vr 模式navigator.xr.isSessionSupported('immersive-vr').then((supported) => {if (supported) {// 请求VR会话navigator.xr.requestSession('immersive-vr').then(sessionStarted);originalDirection = viewer.camera.direction;} else {console.error("未检测到VR设备");}}).catch(() => {console.error("检测失败");});} else {console.error("当前浏览器不支持 WebXR");}}, 200);} else {// 刚退出VR模式if (xrSession) xrSession.end();}});/*** VR会话开始* @param {*} session */function sessionStarted(session) {xrSession = session;// 监听会话结束事件xrSession.addEventListener("end", sessionEnded);// 与普通 WebGL 不同,这里需要设置 xrCompatible 参数gl = viewer.scene.canvas.getContext('webgl', { xrCompatible: true });// gl.makeXRCompatible();// 更新会话的渲染层,后续渲染会渲染在该层上session.updateRenderState({ baseLayer: new XRWebGLLayer(session, gl) });// 请求 local 空间,跟踪用户头部旋转session.requestReferenceSpace('local').then(s => {refSpace = ssession.requestAnimationFrame(onXRFrame); // 开始渲染})}/*** VR会话结束*/function sessionEnded() {// If we have a pending animation request, cancel it; this// will stop processing the animation of the scene.if (animationFrameRequestID) {xrSession.cancelAnimationFrame(animationFrameRequestID);animationFrameRequestID = 0;}xrSession = null;}let lastTransMatrix = [1, 0, 0, 0,0, 1, 0, 0,0, 0, 1, 0,0, 0, 0, 1];/*** 设备渲染帧* @param {*} time * @param {*} frame */function onXRFrame(time, frame) {const session = frame.session;animationFrameRequestID = session.requestAnimationFrame(onXRFrame);// viewer.scene.render()const pose = frame.getViewerPose(refSpace)// 获取旋转和视图信息if (pose) {let glLayer = frame.session.renderState.baseLayer;// Bind the WebGL layer's framebuffer to the renderergl.bindFramebuffer(gl.FRAMEBUFFER, glLayer.framebuffer);// Clear the GL context in preparation to render the new framegl.clearColor(0, 0, 0, 1.0);gl.clearDepth(1.0);                 // Clear everythinggl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);pose.views.forEach(view => {let viewport = glLayer.getViewport(view);gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);gl.canvas.width = viewport.width * pose.views.length;gl.canvas.height = viewport.height;// 视角映射if (view.eye == 'left') {// let matrix = Cesium.Matrix4.fromRowMajorArray(view.transform.inverse.matrix, new Cesium.Matrix4());// let result = Cesium.Matrix4.multiplyByPoint(matrix, originalDirection, new Cesium.Cartesian3());// 矩阵应该使用上次变换的矩阵,而不是从刚进入VR模式后整个过程中的总矩阵let mergedTransMatrix = Cesium.Matrix4.fromRowMajorArray(view.transform.inverse.matrix, new Cesium.Matrix4());let realTransMatrix = Cesium.Matrix4.multiply(Cesium.Matrix4.fromRowMajorArray(lastTransMatrix, new Cesium.Matrix4()),mergedTransMatrix, new Cesium.Matrix4());let result = Cesium.Matrix4.multiplyByPoint(realTransMatrix, viewer.camera.direction, new Cesium.Cartesian3());viewer.camera.direction = result;viewer.scene.render();lastTransMatrix = view.transform.matrix; // 矩阵的逆,作为下次计算基础}})}}// XXX: // 1. 【view.transform.inverse.matrix】矩阵中既包括了头盔旋转变换,也包含了位置平移变换(针对有距离传感器的VR设备),// 最终将整个矩阵应用到了Cesium场景的【camera.direction】,逻辑是不合理的,【camera.direction】应该只对应头盔旋转变换。// The transform property describes the position and orientation of the eye or camera represented by the XRView, // given in that reference space.// 2. 根据[WebXR基础介绍](https://developer.mozilla.org/en-US/docs/Web/API/WebXR_Device_API/Fundamentals#field_of_view),// 左右两只眼看到的应该是有细微差别的。在官方示例中[如https://webxr-experiment.glitch.me/]可以看出,都是将一个canvas分成了// 左右两块区域,然后根据XRView中的左右眼信息分别在两块区域绘制,但是Cesium未暴露出类似【gl.drawElements】的接口,只有// 【scene.render】,调用后只会在整个canvas区域上进行绘制,没有左右分区的效果,所以借助了Cesium自带的VRButton,在进入Cesium// 的VrMode后,再调用WebXR接口连接设备,同时XRView也只处理左眼,利用Cesium自身的左右同步。隐患未知。</script>
</body></html>

4. 效果图

WebXR

5. 参考链接

[1]. WebXR 技术调研 - 在浏览器中构建扩展现实(XR)应用
[2]. 【WebAR】虚拟现实来到网页——WebXR Device API第二部分
[3]. Fundamentals of WebXR
[4]. WebXR: Example with rotating object and user movement
[5]. WebGL 入门
[6]. 【零基础学WebGL】绘制矩形
[7]. Matrix math for the web - MDN
[8]. 旋转变换(一)旋转矩阵


http://chatgpt.dhexx.cn/article/ESswgCCV.shtml

相关文章

一些有意思的VR设备介绍

1.计算机&#xff08;Computers&#xff09; 不久以前&#xff0c;一个VR系统需要百万美元的超级计算机&#xff1b;而如今顶级的VR系统正在使用桌面便携式计算机簇&#xff0c;极大的降低了价格和维护成本。 2.跟踪器&#xff08;Tracking&#xff09; 数据手套的使用不是太多…

Ajax简介与用法

Ajax简介 AJAX 指异步 JavaScript 及 XML&#xff08;Asynchronous JavaScript And XML&#xff09;&#xff0c;Ajax可以实现异步请求。AJAX 是一种在 2005 年由 Google 推广开来的编程模式。 Ajax语法介绍 学习使用Ajax主要就是学习XMLHttpRequest对象的方法和属性 第一个A…

ajax写法和json的知识点

1. JQuery方式来实现AJAX 1.1 $.ajax()方式来实现AJAX 语法&#xff1a;$.ajax(url,[settings]);但是我们一般这么写$.ajax({键值对});。 $.ajax()来实现ajax的案例&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"…

AJAX请求常用的几种写法

1.什么是 AJAX&#xff1f; AJAX 异步 JavaScript 和 XML&#xff08;Asynchronous JavaScript and XML&#xff09;。 简短地说&#xff0c;在不重载整个网页的情况下&#xff0c;AJAX 通过后台加载数据&#xff0c;并在网页上进行显示。 异步加载&#xff0c;局部刷新&am…

ajax的两种写法

一、原生ajax的实现 1.什么是ajax&#xff1f; ajax是异步的javas和xml&#xff08; Asynchronous JavaScript And XML&#xff09;。 通过在后台与服务器进行小量的数据交换&#xff0c;ajax可以使网页实现异步更新。就是说可以在不刷新页面的情况下&#xff0c;对页面的某…

【ajax】ajax详解,ajax是什么?

思路&#xff1a; ajax&#xff1a;&#xff08;asynchronous javascript and xml&#xff09; asynchronous 异步的 ajax是什么&#xff1f; ajax是一种用来改善用户体验的技术&#xff0c;其本质是利用浏览器提供的一个特殊的对象&#xff08;XMLHttpRequest,也可称之为ajax…

Ajax的请求写法详解

简介 是什么 Ajax全称Asynchronous JavaScript and XML&#xff0c;直译过来就是异步的javascript 和 XML。为什么是叫XML还得由于最开始用ajax实现客户端和服务器端数据通信的时候&#xff0c;传输的数据格式一般都是xml格式的数据&#xff0c;所以把它称之为异步js和xml&am…

$.ajax的标准写法

$.ajax({2 url:"http://www.microsoft.com", //请求的url地址3 dataType:"json", //返回格式为json4 async:true,//请求是否异步&#xff0c;默认为异步&#xff0c;这也是ajax重要特性5 data:{"id":"value"}, …

ajax详细用法

一、基础知识 1、首先让我们了解ajax---------------- 通过在后台与服务器进行少量数据交换&#xff0c;AJAX 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下&#xff0c;对网页的某部分进行更新。 2、ajax的核心步骤&#xff1a; 创建XMLHttpReq…

ajax的常见几种写法以及用法

一、服务端数据格式 1.自定义po类 package com.hbut.ssm.po;/*** pojo类**/ public class Children {private String name;private Integer age;private String gender;public Children(String name, Integer age, String gender) {super();this.name name;this.age age;thi…

Ajax的三种写法(最原始的写法+最常用的写法+最简便的写法)

AJAX&#xff1a;Asynchronous JavaScript AND XML 定义&#xff1a;浏览器向服务器发送的异步请求&#xff08;不改变页面的情况下&#xff0c;发送的变化&#xff09; 核心&#xff1a;浏览器向服务器发送异步请求&#xff0c;javascript中提供xmlHttpRequest对象&#xf…

利用油管语音转文字

https://www.tunestotube.com/ 音频上传油管https://zhuwei.me/y2b/ 获取油管字幕文章转载自 https://www.jianshu.com/p/762ae8461243

怎样能把文字变成语音

文字转语音目前在人们的生活和工作中发挥着很大的作用&#xff1b;没事的时候人们总是喜欢看看手机新闻或者玩玩电脑游戏&#xff0c;我们在看新闻的内容时&#xff0c;长时间的盯着屏幕看文字&#xff0c;很快会让眼睛变的疲劳&#xff0c;如果想要让眼睛得到休息又能够获取新…

Java文字转语音功能实现

也许&#xff0c;有些时候&#xff0c;你需要这个需求呢&#xff0c;来上代码 我会写出两种不同方式的文字转语音demo&#xff0c;直接copy走用&#xff0c;节省开发时间 git项目下载地址 1.直接使用jdk的 jacob&#xff0c;效果还不错&#xff0c;特点&#xff1a;免费的 2…

电脑文字转语音怎么弄?这些方法值得一试

有时我们需要在上网搜索一些文献作为参考&#xff0c;但有些资料文字太多&#xff0c;内容枯燥&#xff0c;不是很想阅读。这时我们可以将网页文字转成语音&#xff0c;就不用一直盯着屏幕上的文字&#xff0c;通过“听”的方式&#xff0c;还可以让我们放松下来。那么你知道网…

视频语音识别文字

广告关闭 9.9元享100G流量包&#xff0c;1年有效&#xff0c;低至1元/天&#xff0c;具备美颜动效视频处理等功能&#xff0c;支持定制开发&#xff0c;最快1天接入。 腾讯云语音识别服务开放实时语音识别、一句话识别和录音文件识别三种服务形式&#xff0c;满足不同类型开发…

如何将视频的语音变成文字播放出来?

看到回答中很多人分享的是软件&#xff0c;每次使用都需要下载&#xff0c;给大家分享两款在线端语音转文字工具&#xff0c;不用下载安装&#xff0c;在线登录就能使用&#xff0c;非常方便。 1、网易见外 网易见外是网易团队上线的一款转文本工具&#xff0c;上线了视频转写…

如何才能实现文字转语音播放?只要这三个步骤就能快速搞定!

大家知道吗&#xff1f;配音已经不再是影视制作的专属工作了&#xff0c;如今随着各种短视频平台的热度上涨&#xff0c;许多普通用户也加入到短视频的制作中&#xff0c;市面上也陆续出现许多专门服务于这类人员的配音工具&#xff0c;依托它们&#xff0c;大家无需进行人工配…

手把手教你实现——Python文字(汉字)转语音教程,举一反三~

前言&#xff1a; 这是一篇简单的Python文字&#xff08;汉字&#xff09;转语音教程&#xff0c;当然对于其他语言工具在实现的方法上也是一样的 。 在自然语言处理上&#xff0c;文字、音频互转是一个很关键的技术点。对于语音转文字&#xff0c;个人实现较为困难&#xff…

在线文字转成语音怎么转

很多小伙伴在办公或学习中&#xff0c;经常或需要浏览大量资料。随着时间越来越长&#xff0c;我们的眼睛就会多度疲劳。为了不戴上眼镜&#xff0c;我们只能改变当前的方式&#xff0c;也就是把文字变成语音去听&#xff0c;而不是去看。那么就有小伙伴想问了在线文字转成语音…