基于ue4的云渲染目的在与将ue4实时渲染图像帧通过视频流的方式一帧一帧的传到浏览器端,主要是因为基于web的三维渲染效果不佳,通过ue4的强大渲染能力与各种功能的支持能力使得网页端也可以实时看到好的效果。
这个过程服务之间使用的是反向代理的机制,过程大概分为三个应用:
前端------(控制命令与视频流)node信令服务--------ue4视频流服务。
知识准备工作:
1、前端:web端需要通过html+js的方式显示视频与后端交互,需要熟悉前端的一些知识;
2、信令服务:基于nodejs开发的服务,接受前端发送过来的命令,并将命令转发到ue4服务端,同时接受ue4服务端发送过来的视频流与其他信息转发给前端;
3、ue4服务端:接收信令服务的控制命令信息,根据命令调用相应的功能进行渲染,将渲染结果发送给信令服务。
开发过程:
1、建立ue4工程(本人使用的是4.26版本)名称是"Test",开启"Pixel Streaming"插件。
2、打包工程,打包之后会在生成的目录中包含"node的信令服务",例如:打包目录"D:\WindowsNoEditor",
3、信令服务
信令服务的目录是 "D:\WindowsNoEditor\Engine\Source\Programs\PixelStreaming\WebServers",在"WebServers\SignallingWebServer"文件夹下,包含一些用于启动node的批处理文件。例如run.bat文件
:: Copyright Epic Games, Inc. All Rights Reserved.
@echo off
pushd %~dp0
call setup.bat ::调用另一个批处理文件(用于安装依赖的npm包)
title Cirrus ::窗口标题
::Run node server
::If running with frontend web server and accessing outside of localhost pass in --publicIp=
node cirrus %* ::启动js脚本服务
popd
pause
其中cirrus.js文件会读取"config.json"中的配置信息启动node服务,这些配置信息比较重要的是一些ip地址和端口,"config.json"如下:
{
"UseFrontend": false,
"UseMatchmaker": false,
"UseHTTPS": false, //是否使用https
"UseAuthentication": false, //认证信息
"LogToFile": true,
"HomepageFile": "Player.htm", //访问的主页
"AdditionalRoutes": {},
"EnableWebserver": true,
"httpPort": 82, //前端网页的访问地址
"streamerPort": 8888 //ue4流服务的注册地址
}
由于"run.bat"目录比较深,可以使用快捷方式或者重新定义bat的方式启动,例如:
::信令服务启动
@echo off
call "WebServers/SignallingWebServer/run.bat"
启动信令服务之后会出现下面的窗口
绿色的部分显示了ue4流服务链接的端口8888,web端链接的端口80,在网页中输入"localhost:80"就可以打开页面,
3、ue4渲染服务
ue4服务的目录是 "D:\WindowsNoEditor\Test.exe",单纯启动这个程序不会链接到信令服务,需要配置一些参数,例如创建快捷方式,通过在快捷方式的属性中输入一些配置命令,由于"Test.exe"目录比较深,可以使用快捷方式或者重新定义bat的方式启动,例如:
@echo off
start WindowsNoEditor/PixStreamServer.exe -ResX=1920 -ResY=1080 -PixelStreamingIP=localhost -PixelStreamingPort=8888 -log -RenderOffScreen
::参数解析
::ResX、ResY设置窗口的分辨率
::PixelStreamingIP 信令服务的ip
::PixelStreamingPort 信令服务的端口
::log 日志
::RenderOffScreen 是否显示ue4服务窗口
开启"ue4服务"后,点击网页会显示如下界面表明已经开启
同时"信令服务"界面会显示链接信息
4、命令转发
前端需要编写调用的命令, 调用命令的传递方式是以json格式传输的,所以前端需要调用相应的接口将json数据传输出去就可以了。
打开前面信令服务文件夹下的"config.json",可以看到"HomepageFile": "Player.htm", 访问的主页,主页的代码如下:
可以看到脚本中引用了
这两行,其中"webRtcPlayer.js"用来播放,而"app.js"中有很多传输命令的接口。
app.js文件中的部分代码如下
。。。。。。
function sendInputData(data) {
if (webRtcPlayerObj) {
resetAfkWarningTimer();
webRtcPlayerObj.send(data);
}
}
// A generic message has a type and a descriptor.
function emitDescriptor(messageType, descriptor) {
// Convert the dscriptor object into a JSON string.
let descriptorAsString = JSON.stringify(descriptor);
// Add the UTF-16 JSON string to the array byte buffer, going two bytes at
// a time.
let data = new DataView(new ArrayBuffer(1 + 2 + 2 * descriptorAsString.length));
let byteIdx = 0;
data.setUint8(byteIdx, messageType);
byteIdx++;
data.setUint16(byteIdx, descriptorAsString.length, true);
byteIdx += 2;
for (i = 0; i < descriptorAsString.length; i++) {
data.setUint16(byteIdx, descriptorAsString.charCodeAt(i), true);
byteIdx += 2;
}
sendInputData(data.buffer);
}
// A UI interation will occur when the user presses a button powered by
// JavaScript as opposed to pressing a button which is part of the pixel
// streamed UI from the UE4 client.
function emitUIInteraction(descriptor) {
emitDescriptor(MessageType.UIInteraction, descriptor);
}
。。。。。。
// 下面是我自定义按钮的处理函数
function ButtonTest1(){
let data = {
"type":"test1",
"number":1.0,
"bool":true,
"string":"xiaoming",
"subObject":{
"name":"xiaoming",
"age":15
}
};
emitUIInteraction(data);
}
可以看到emitUIInteraction是app.js封装的接口,有助于我们传输json数据。
5、ue4命令接收命令
ue4中接收信令服务转发过来的命令使用的是"PixelStreamerInput"插件,一般情况下我们自己创建ue4项目时会创建自己的gamepaly结构,其中gamemode是组织其他功能的一个类,所以通常将"PixelStreamerInput"插件挂到gamemode下面,在蓝图下添加如下节点:
"PixelStreamerInput"插件内置了接收前端数据、解析json、发送数据的接口。
备注:为了调试方便,可以在ue4的编辑器设置中添加启动参数,这样就不用每次发布出来用exe启动项目了;
over