Cesium集成WebXR_连接VR设备
Posted wml00000
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Cesium集成WebXR_连接VR设备相关的知识,希望对你有一定的参考价值。
Cesium集成WebXR
文章目录
1. 需求
通过WebXR接口,将浏览器端连接到VR头盔,实现在VR头盔中浏览Cesium场景,并可将头盔旋转的操作同步映射为场景视角的变换,实现沉浸式体验。
2. 技术基础
2.1 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 其他
另外需要了解一些矩阵变换(平移、缩放、旋转)知识,可参考以下链接:
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 = s
session.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 renderer
gl.bindFramebuffer(gl.FRAMEBUFFER, glLayer.framebuffer);
// Clear the GL context in preparation to render the new frame
gl.clearColor(0, 0, 0, 1.0);
gl.clearDepth(1.0); // Clear everything
gl.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. 效果图
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]. 旋转变换(一)旋转矩阵
Chrome支持全新的WebXR标准 VR/AR体验更方便
谷歌在追求新技术方面一直与时俱进,在VR领域也有一席之地,而为了让VR/AR体验变得更加方便,谷歌则为Chorme浏览器添加了WebXR API,并且提升了后台性能和稳定性。
Chrome 67浏览器支持全新的WebXR 标准,允许开发人员创建在所有VR/AR设备都可运行的沉浸式内容,以实现基于Web的VR/AR体验。
Chorme 67除了新增WebXR API之外,另外还支持新的通用传感器API(Generic Sensor API),使开发人员可以轻松获取传感器数据。通过新的通用传感器API,网站将可以访问移动设备或PC端可用的各种传感器,如加速度计、陀螺仪、方向传感器和运动传感器,以构建沉浸式体验。
目前,新API依然处在测试阶段。此测试版还包含开发人员预览版,用以支持WebXR API。新的WebXR标准基本参考现有的WebVR标准,并在顶部添加AR功能。
为了提升VR/AR体验,不少巨头企业都在不断攻克技术难关,相信随着技术的不断完善,未来VR/AR体验将会变得更加出色,届时也将会有更多的企业和用户加入到VR/AR大军当中。
沈阳体育学院坐落于辽宁省省会沈阳市,学校环境优美,清新自然,尽显体育高校的运动精神。为了让更多人了解学校,合作推出了沈阳体育学院全景漫游,通过沈阳体育学院全景漫游学校的活力显露无疑。
沈阳体育学院是新中国建立最早的体育院校之一,原名东北体育学院,成立于1954年,是辽宁省唯一一所中央与地方共建、以体为主、多学科多专业协调发展的高等体育院校。学校设有12个二级教学单位、2个附属学校,有19个本科专业,跨教育学、管理学、文学、理学、艺术学5个学科门类。
学院承担着国家体育总局自由式滑雪、U型场地单板技巧项目参加亚冬会、冬奥会比赛代表队的组建、管理和训练工作,承担辽宁省拳击、蹦床、跆拳道、棒球、短道速滑、速度滑冰等六个项目的训练工作。
同时学院与日本、韩国、美国、英国、澳大利亚、俄罗斯、奥地利等国家和台湾地区共20多所院校建立了友好校际关系,广泛开展学术交流与科研合作。学院在国内率先引进了软式网球、自由式滑雪、木球、冰撬、单板滑雪、U型场地单板雪上技巧等运动项目,实力雄厚。
通过推出的沈阳体育学院全景漫游我们能够尽情欣赏学校的美景。沈阳体育学院全景漫游将学校的清新环境和现代化建筑一一展现了出来,带给人们赏心悦目的沉浸感。
更多干货请点击
| |
| |
| |
| |
©本文版权归 VR界的搬砖小哥 所有
任何形式转载请联系作者
以上是关于Cesium集成WebXR_连接VR设备的主要内容,如果未能解决你的问题,请参考以下文章