像素流模块
npm install --save iver-pix
Web浏览器在渲染3D模型时,往往依赖的是客户端GPU的渲染能力,很多时候,由于客户端的渲染能力不足, 导致在呈现复杂场景时,客户端无法流畅的运行项目,导致用户体验不佳。 Web浏览器呈现3D场景常用的框架包括Three.js、Babylon.js、A-Frame,以及结合GIS的Cesium等。 这些框架都是基于WebGL,依赖客户端的渲染能力,有时会在开发人员机器上运行流畅的程序, 到客户使用时会受到客户机器GPU渲染能力的限制,无法得到流畅体验。
CloudStream不同于WebGL的渲染方式,它采用的是像素流(UE云渲染),将渲染交给服务器,在云端渲染, 以像素流推送到客户端,从而使复杂场景、大模型的渲染不再需要依赖于高性能的客户端。且对于开发者, 这一过程是透明的,接入UE云渲染的Web程序,无需关心它的底层构架和通信机制,只需引入CloudStream提供的依赖模块, 即可将虚幻引擎引入到Web程序,从而实现虚幻引擎和Web程序的交互。
在很多时候,我们并不能说UE云渲染的方式是更优的解决方案,在有大量客户端需要同时连接到服务器访问的时, UE云渲染的服务器需要更强大的GPU计算能力和足够的带宽。可以把UE云渲染想象成一个视频服务器。所以这样的情况, 考虑到成本投入,我们更建议采用WebGL的方案。
你可以把它想象成一个多人协作虚拟场景。利用像素流技术能够开发高性能图形渲染的应用项目, 可以将3D场景的渲染过程移至远程服务器,然后将渲染结果流式传输到客户端的Web浏览器,从而实现高度交互性和实时性。
数字孪生模拟:结合虚拟现实技术和数字孪生模型,可以创建高度沉浸式的虚拟环境,让用户可以在虚拟空间中与数字孪生模型进行互动和操作。像素流技术可以用于将虚拟现实数字孪生模型的视觉内容实时传输到大屏幕上,使用户可以在一个全息的、立体的环境中进行模拟和实验,例如在工厂中进行设备维护和优化,或者在城市中进行交通规划和管理。
大屏可视化控制台:利用大尺寸屏幕来展示各种数据和信息,以便更好地理解和管理复杂的系统和流程。像素流技术可以将大量的数据和图像实时传输到大屏幕上,使用户可以在一个集中的、高清的界面上监控和控制多个数据源和设备,例如监控中心、交通指挥中心、能源管理中心等。
npm create vue@latest //创建一个vue脚手架【默认安装即可】
npm i //安装依赖
npm install --save iver-pix //安装像素流模块
执行成功后
删除 /src/assets/main.css的默认样式代码
删除 /src/App.vue的默认代码
复制如下代码到App.vue ↓↓↓
<!-- vue-js引入 -->
<template>
<!-- <a href="javascript:void(0)" @click="handleClick()">发送消息1</a>
<a href="javascript:void(0)" @click="handleClickAsync()">发送消息2</a> -->
</template>
<script setup>
import { onMounted, ref } from "vue";
import CloudStream from "iver-pix";
const cloudStream = ref(null);
onMounted(() => {
//创建渲染-执行该方法,就能将ue引入到网页-其他方法按需求调用
cloudStream.value = CloudStream.Create({
wsPath: "127.0.0.1:88", //通信和信令服务器通信的sokect地址 -不填默认为127.0.0.1:88
});
// //监听虚幻引擎发送给web的消息-为固定格式{ cloud: "cloudName", data: string|object|arrary, ... };
// cloudStream.value.listener((res) => {
// //通过虚幻引擎给定的cloud值判断- 【依照具体需求】
// switch (res.cloud) {
// case "cloudName1":
// console.log(res);
// break;
// case "cloudName2":
// console.log(res);
// break;
// default:
// console.log(res);
// }
// });
// //监听渲染是否完成
// cloudStream.value.beginPlay(() => {
// console.log("开始渲染");
// });
});
// function handleClick() {
// //web向虚幻引擎发送消息为固定格式:{ action: "actionName", data:string|object|arrary},要实现具体功能,send方法需要传递的参数参照调用文档
// //向虚幻引擎发送消息,不需要接收虚幻引擎返回消息-按需求使用
// cloudStream.value.send({
// action: "actionName1",
// data: { id: 1 },
// });
// // //向虚幻引擎发送消息,需要异步接收虚幻引擎返回消息-按需求使用
// // cloudStream.value.send({
// // action: "actionName2",
// // data: { id: 2 },
// // callback(result) {
// // console.log(result);
// // },
// // });
// }
// async function handleClickAsync() {
// //sendAsync同send功能一样,将send封装成了Promise
// const result = await cloudStream.value.sendAsync({
// action: "actionName3",
// data: { id: 3 },
// });
// console.log(result);
// }
</script>
<style></style>
//在vue-project目录下执行
npm run dev
启动成功后运行
http://localhost:5173/
<!-- vue-ts引入 -->
<template>
<!-- <a href="javascript:void(0)" @click="handleClick()">发送消息1</a>
<a href="javascript:void(0)" @click="handleClickAsync()">发送消息2</a> -->
</template>
<script setup lang="ts">
import { onMounted, ref } from "vue";
import CloudStream from "iver-pix";
const cloudStream = ref<CloudStream | null>(null);
onMounted(() => {
//创建渲染-执行该方法,就能将ue引入到网页-其他方法按需求调用
cloudStream.value = CloudStream.Create({
wsPath: "127.0.0.1:88", //通信和信令服务器通信的sokect地址 -不填默认为127.0.0.1:88
});
// //监听虚幻引擎发送给web的消息-为固定格式{ cloud: "cloudName", data: string|object|arrary, ... };
// cloudStream.value.listener((res) => {
// //通过虚幻引擎给定的cloud值判断- 【依照具体需求】
// switch (res.cloud) {
// case "cloudName1":
// console.log(res);
// break;
// case "cloudName2":
// console.log(res);
// break;
// default:
// console.log(res);
// }
// });
// //监听渲染是否完成
// cloudStream.value.beginPlay(() => {
// console.log("开始渲染");
// });
});
// function handleClick() {
// //向虚幻引擎发送消息为固定格式:{ action: "actionName", data:string|object|arrary},要实现具体功能,send方法需要传递的参数参照调用文档
// //向虚幻引擎发送消息,不需要接收虚幻引擎返回消息-按需求使用
// cloudStream.value?.send({
// action: "actionName1",
// data: { id: 1 },
// });
// // //向虚幻引擎发送消息,需要异步接收虚幻引擎返回消息-按需求使用
// // cloudStream.value?.send({
// // action: "actionName2",
// // data: { id: 2 },
// // callback(result) {
// // console.log(result);
// // },
// // });
// }
// async function handleClickAsync() {
// //sendAsync同send功能一样,将send封装成了Promise
// const result = await cloudStream.value?.sendAsync({
// action: "actionName3",
// data: { id: 3 },
// });
// console.log(result);
// }
</script>
<style></style>
<!-- html原生引入 -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<!-- 检查引用路径 -->
<script src="./cloudstream.js"></script>
<script>
window.onload = function () {
const cloudStream = CloudStream.Create({
wsPath: "127.0.0.1:88",
});
cloudStream.beginPlay(() => {
console.log("开始渲染");
});
};
</script>
</head>
<body></body>
</html>
class CloudStream {
// 类的静态属性
public static instance: CloudStream | null;
// 公共静态方法,用于获取类的单一实例
public static Create(options?: { ... }): CloudStream { ... }
// 监听特定ue消息的方法
listener(callback: (res: { cloud: string; data: any }) => void, sendName: string = "cloud") { ... }
// 开始播放
beginPlay(callback: () => void) { ... }
// 发送send请求的方法
send({ action, data, callback }: { ... }) { ... }
// 发送send请求并返回Promise的方法
sendAsync({ action, data }: { ... }): Promise<any> { ... }
// 释放资源-即销毁
dispose() { ... }
}
Create(options?: {
wsPath?: string; //与服务器的sokect通信地址
//显示样式 因为像素推流默认会推送16:9,当然这个因需求而定,所以适配需求和各类设备设置了三种样式。
//fit:将16:9【或其他比例】的流送按照浏览器的宽和高拉伸显示,
//cutFit:在浏览器视口保持16:9【或其他比例】最大范围的保证流送完整显示。流送为主。
//maxFit:保持浏览器视口宽高显示流送。浏览器为主。
viewType?: "fit" | "cutFit" | "maxFit";
isBorder?: boolean; //显示border,调试时可开启
zIndex?: number;
rateWidth?: number;
rateHeight?: number;
})
default option {
wsPath = "127.0.0.1:88",
viewType = "cutFit",
isBorder = false,
zIndex = -1,
rateWidth = 16,
rateHeight = 9,
}