Unreal Engine4入门及广电应用探索

一、引言

Unreal Engine4(简称UE4)被大家广为熟知应该是在游戏应用领域,之前玩过的《堡垒之夜》、《八方旅人》,《底特律:变人》,还有最近出的《龙珠战士Z》、《血迹:暗夜仪式》,以及即将推出的《赛博朋克2077》、《最终幻想7重置版》,不管是3A的还是独立制作人的,大家都可以通过UE4实现自己的游戏创作梦。UE4放开了游戏制作的门槛,也给其他领域,如设计包装、机械生产、广电影视打开了新的大门,只要你有想法肯花时间,就可以花最小的代价做最有趣的事情。

本人从事广播电视制作相关工作,之前我们接触的包装最多的还是Vizrt、Orad、Dayang、新奥特这类传统广电包装。有专门的美编人员负责包装的设计制作,也有专门的播控系统对接演播室播出,包装设计相对封闭,播出操作简单易学,以至于很多传统做广电在线包装的人转UE4时都有个疑惑-在UE4里面,我到底时设计还是技术还是播控?我的答案是,在UE4里面,我就是上帝,我负责一切。

二、UE4学习入门

UE4我也是刚接触学习将近一个月,我并非美编从业人员,不会3DMAX和MAYA,算是小白中的小白,学习心得有不当之处还望高手指正。

2.1、搞清楚一些常用单词及术语

UE4虽然内置了一些模板,而且有很多“入门到精通”的书,我也买了几本,但是不建议上手直接开干,之前没有基础的话先做好一些相关术语的功课,略微总结如下:

1.蓝图(Blueprint)——传说中不会编程的用了蓝图就能轻松上手UE4,我觉得是扯淡,蓝图是图像化的编程语言,如果没有编程的逻辑,不知道类、对象、继承这些,也没法用蓝图,蓝图广义上理解就相当于程序模块,包含三种类型关卡蓝图(Level Blueprint)、蓝图类(Blueprint Class)、蓝图插件(Widget Blueprint)、蓝图接口(Blueprint Interface)、蓝图函数库(Blueprint Function Library)、蓝图宏库(Blueprint Macro Library)。学过编程的从字面意思上就能很好理解,关卡蓝图相当于关卡场景的入口函数,蓝图类相当于函数中的类,可继承重定义,蓝图插件相当于图形化编程,添加类似按钮、画布、文本类的内容。这些类的详细的用法在书本或者操作手册上都会提及,最重要的还是需要用编程的思维去设计场景。

2.静态网格和BSP——静态网格也称作(static mash),即固定大小、形状的物体骨架,用3D Max或者MAYA做好的模型,可直接导入UE4,相当于一个静态网格;BSP是UE4内部的几何模型,新版本里面也称为Geometry,它和静态网格的区别是,BSP放开了对几何形状的调整,可自由的拼接拆分,而静态网格不行。因此BSP渲染上的开销要比静态网格大很多,BSP可以转成静态网格。

3、Actor——通用的一个基类,支持三维变化、平移、旋转、缩放,UE4里面所有的类都从继承它而来。

4、Pawn、Play Controller、Character——很多场景中都会出现这几类对象,字面上看着都差不多,Play Controller相当于一个控制器,玩家可以通过控制器去操作对象,Pawn是一个接收控制器输入的Actor,Charactor是一个人形(或者动物)的Pawn,它包含的行走,跑步,跳跃。Pawn是看不到的,但是它通过Play Controller可以帮助你(第一人称)在3D场景中做各种移动,Character是一个有型的物体(第三人称),你可以去控制这个物体在3D场景中移动。

5、Game Mode——直译为游戏模式,指定游戏(项目)的规则,预加载的文件等,可以设置玩家和观众数量,如何进入游戏,游戏状态和玩家状态等,可以理解为整个项目的初始化过程。

6、材质(Material)——UE4说的最多,吹的最多的就是材质,其他引擎里也有材质,但更UE4相比真实感上还是会差很多。材质本质上对贴图(Texture)进行加工,模仿出类似金属、木材、玻璃等各种不同的表面,让模型看上去更真实。

7、粒子(Particle)——类似于火焰、雨滴、爆炸这类特效,每个粒子都有发射器(Spawn),用来控制例子发射的状态,粒子也是最考虑运算材质,一般放在GPU里面运算,如果电脑或者手机的GPU运算不够的话,也可以通过材质贴图来模仿粒子的运动。

2.2、用编程的思维去做场景

UE4内部自带的类以及通过网上下载的插件中,包含中无数种的方法,就像学习编程一样,你是没法搞清楚这里面所有的方法和功能,只有随着不停的做项目去积累,取自己所需的那部分就够了。UE4本质上是一款编程工具,最先需要了解的是程序的入口和程序的实现方式。

1、项目的开始——UE4项目文件后缀为“uproject”,一个项目里面可以包含很多个关卡(Level),关卡相当于一个个游戏场景,当编译运行项目时,首先确定Game Mode,即对应加载项目初始化需要的特定模块,Game Mode和对应加载模块可自定义,初始化时运行Game Mode下的模块。

2.关卡的入口——Level Blueprint,关卡程序的入口,当进入关卡后首先执行对应关卡的Level Blueprint,在Blueprint里面可以指定事件,制定相关的事件操作,也有人会在关卡蓝图里进行关卡的初始化操作。

3、Event Begin Play,Event Tick——所有蓝图里面用到的最多的两个类,Event Begin Play表示蓝图开始执行时的事件,只在蓝图开始执行时运行一次,可通过Event Begin Play做相应蓝图初始化工作;Event Tick蓝图主循环事件,蓝图执行后会不停的去触发Tick事件,可对该事件设定触发间隔时间。

4、其他蓝图——类、接口、宏、插件,说白了就是面向对象的编程方法,基于C++来实现,实际操作起来跟码代码是一样的。UE4有自己的虚幻商城(MarketPlace),需要什么插件、材质、项目,都可以从虚幻商城下载,在使用这些插件和方法的时候,蓝图就比直接手打来的方便快捷多了,比如说你想要实现什么方法,在蓝图的事件图表内右击,就会有相关索引出现,依据自己的意思,输入英文就可以找到对应方法。就像聊天,你告诉蓝图你要什么,它会给你什么,然后你自己把你要到的东西拼接起来,就能实现自己想实现的。

三、UE4结合BlackMagic视频IO卡案例分析

3.1、准备工作

之前的所有概念介绍,目的就是实现应用,庆幸的是UE4商城上有免费的视音频卡采集案例给我们学习虚拟工作室,我就运用下刚学的内容,对这个案例进行分析,让大家更详细的了解它怎么实现的。此次学习测试用到的视频卡是BlackMagic Decklink Quad卡,4路SDI输入,4路SDI输出,1路模拟同步输入,主机位HP Z800工作站,系统WIN10,显卡Nvidia K5200,UE4软件版本是目前最新的4.22.3。UE4商城上下载“Virtual Studio”工程,以及“BlackMagic Design Media Player”视频卡插件,都是免费的,同时我发现“Virtual Stduio”工程中还支持AJA的视频卡,“AJA Media Player”视频卡插件同样也可以从UE4商城免费下载,一个“Virtual Stduio”工程中支持两类视频卡的输入输出,会在后面提及。

3.2、“Virtual Stduio”工程分析

我们从之前学习入门获得的思路上展开学习,项目进入时先看Game Mode,再看Level BluePrint,然后看各类蓝图类,最后再看场景中的应用

3.2.1 Game Mode


Virtual Studio Game Mode

在Blueprint-项目设置-游戏模式下,可以看见预加载的Game Mode文件是“GameModeBase.h”,这是个基类的Game Mode,也就是项目没对Game Mode进行修改,使用的默认配置,在此我们就不去深究这个Game Mode基类是做什么的了,主要瞄准项目关键的程序节点。

3.2.2、Level Blueprint

Virtual Studio项目中就一个Level Blueprint,说明只加载一个场景文件,在Blueprint-关卡蓝图-打开关卡蓝图,事件图标中有两个事件:Event Begin Play->Excude Console Command,执行控制台命令“r.SSR.Quality 4”,简单查阅这个命令,就是将UE4渲染效果开到最高;按任意键->On Key Released Event,获取CameraSwitcher这个类的实例(在场景中有对应实例),同时执行该类下On Key Released Event的方法。Level Blueprint目的很明确,初始化关卡配置和实例,等待键盘的输入(键盘可作为Camera信号的切换)。


Level Blueprint

3.2.3、CameraSwitcher

CameraSwitcher为蓝图类,在Blueprint-关卡蓝图-打开蓝图类中打开,也可直接双击On Key Released Event索引到该类下的方法函数。我们先看CameraSwitcher的事件图表,通过Event BeginPlay事件可看到,在CameraSwitcher类实例化的时候,会执行四步操作:

1、禁用Pawn的输入控制,初始化视频卡中输入的Camera信号,从蓝图的流程中可以看到,流程中禁用了Player Pawn(不能在场景中自由走动),打开了鼠标指针显示(Show Mosue Cusor),同时对每个Camera进行初始化操作,CameraList是一个数组变量,里面存放着具体的Camera对象,Initialize是VirtualSetMediaInput类下面的函数方法,它的主要作用是获取视频输入信号对象下附属的Camera对象,说白了就是获取拍摄场景中虚拟摄像机对象。


Disable Player Inputs and Initialize registered cameras

Camera信号初始化操作流程如下图


Intialize

2、设置AJA的视频输出,同样也适用于设置BlackMagic的视频输出,该流程是获取视频输出口的对象,创建视频抓取的方法,等待视频输出。VideoOutputSettings是视频输出变量,EnableOutputByDefault是布尔值变量,控制视频的输入和输出,EnableVideoCapture是Cameraswitcher类下面的方法函数,接收EnableOutputByDefault的值,从字面意思上使能视频输出。


Setup AJA Video Output

我们不妨再看一下EnableVideoOutput的具体操作方法,双击打开它,根据接收的布尔值进行分支处理,如果是真,就将对应视口上的内容输出给视频输出卡(CaptureActiveSceneViewport),如果是假,就停止输出(StopCapture)。


EnableVideoOutput

3、准备视频输入源切换的UI插件,CameraSwitcherUI是一个蓝图插件类,在Content->VirtualSet->Blueprints目录下可打开查看,此UI控件的作用就是切换场景中的视口(Viewport),不同的视口对应不同的外部视频输入源,同时控制视口的视频输出,具体UI控件的内容后面再做探讨。此处创建CameraSwitcherUI后做了四步,将UI控件和场景中的CameraSwitcher对象进行关联(Set CameraSwitcher),创建Camera信号预监(CreateCameraViews),将插件放到视口(AddtoViewport),将插件内的Checkbox关联到输出信号使能(SetIsChecked)。


PrepareCameraSwitcherUI

CreateCameraView事件是CameraSwitcherUI类下面的方法,该事件方法比较复杂,双击打开对应事件,流程上可分为5步:

a.从Camera Switcher这个变量(在之前第3步中已经将CameraSwitcher实例和UI中的这个CameraSwitcher变量做了关联),循环读取Camera输入对象。


Get all cameras from CameraSwitcher

b.创建预监的插件,并放到HorizonBox99这个画布下面,Loop出来又两个Camera输入信号就放两个,有三个就放三个。


Create CameraView Widget and Attach CameraSwitcher

c.创建一个材质实例,然后将视频信号贴到材质上,视频信号需要实现转换成动态贴图。


Create Material Instance and set Media Texture as input

d.设定预监窗口下的标签名字,标签名从输入信号的对象名中读取。


Set  Camera Name from user input if any.Take texture name if none

e.设定预监窗口的材质


Set Material on our CameraPreview Widget

4、选择默认的Camera信号源,Select Camera是CameraSwitcher类下面的事件方法,双击打开它继续探究。


Select first camera

SelectCamera的流程图如图所示,CameraSwitcher类中的GoToCamra、GoToNextCamera方法,最终都会调用SelectCamera,它里面定义了一套逻辑,用来表示如何切换不同视频源。SelectCamera流程上可分为4步:

a.将输入的CameraID设定为NewCamera,并检查输入CameraID是否有效


Validate Camera is Valid

b.关闭旧的输入信号显示,并打开新的输入信号显示,切换不同的Camera会对应不同的输入信号源。


Handle plate visibility when switching camera

c.打印一段文字,显示目前切换的CameraID。


Log Camera Switch

d.执行切换Camera操作,主要用到Set View Target With Blend,函数方法里面还能设置切换的方法,此项目中用到的是VTBlend Linear。


Perform Camera Swicth

3.2.4、Virtual Studio场景

VirtualSetMediaInput、CameraSwitcherUI、CameraViewWedget所有这些Blueprint类和插件都服务于CameraSwitcher类,而CameraSwitcher类和VirtualSetMediaInput类被放入到场景中实例化,并且在Level Blueprint中进行了调用,每个类和插件中也都带有初始化的一些方法,在此不做复述,有兴趣的小伙伴可以自行深入研究,我们继续最后一步分析,看场景。

Virtual Studio场景制作的非常精良且复杂,各种贴图、灯光、桌面、楼梯等,这里面随便拿一些元素进行查看就有很多学问,此次学习我们重在了解流程,先不关注场景中的材质贴图,重点在场景中VirtualSet目录下的内容,CameraSwitcher、VirtualSetMediaInput1、VirtualSetMediaInput2.


World Outliner

1、CameraSwitcher,是CameraSwitcher蓝图类实例化的对象,该类放开了对Camera List、Show UI、Video Output变量的修改,可以在场景中选中CameraSwitcher对象,直接对该对象进行初始化修改,如下图所示。Video Output加载选中的是MediaOutputProxy_01,我们暂时把它当作BlackMagic视频卡的输出代理文件,后面还会相信介绍视频输入输出代理的配置;Camera List,加载了两个元素VirtualSetMediaInput1和VirtualSetMediaInput2,也是场景中的元素,是VirtualSetMediaInput蓝图类的实例化对象,作为两路Camera信号;Show UI是布尔值,表示默认加载CameraSwictherUI(参考CameraSwitcher蓝图类的流程说明)。CameraSwitcher对象是一个全局对象,在任何蓝图类和插件中都能调用,主要拖拽进去就行。


CameraSwitcher对象

2、VirtualSetMediaInput1、VirtualSetMediaInput2,是VirtualSetMediaInput蓝图类的实例化对象,相面还跟了一个Camera,是cine camera actor类的实例对象,负责提供VirtualSetMediaInput1/VirtualSetMediaInput2的拍摄视口。以VirtualSetMediaInput1为例,如下图所示,它放开了Plate Distance和Camera Name两个变量的修改选项,Plate Distance是设定Camera和输入信号之间的距离,图中显示的是4,及表示距离是400cm(具体位置关系可查看VirtualSetMediaInput类中Construction Script函数),Camera Name就表示摄像机名字,在预监窗口中会使用到;Media Bundle表示输入信号源,默认加载配置文件VideoBundle_01,后面会具体介绍。


VirtualSetMediaInput1对象

3.2.5、视频的输入输出

此次测试使用的BMD Decklink Quad卡,通道上是4入4出,实际上只是一张4通道卡,入出不能同时在一个通道上执行,因此我们此次通道分配上,前两路通道作为输入,第三路通道作为输出。视频输入输出的配置文件在Content->VirtualSet->MediaProfiles->FileMediaProfile,FileMediaProfile是媒体描述文件,入下图所示,输入和输出可通过UE4商城下载的BMD插件来选择Decklink卡的通道,在configuration下可配置视频通道,Video下可配置采样率,输入输出选择是8bit YUV采样。


FileMediaProfile

FileMediaProfile如何去对应场景中的具体对象,我们继续往下。在UE4工程文件Edit->ProjectSettings->Plugins->MediaProfile,可设置场景初始化加载的媒体文件,已经媒体文件中的配置,具体指向的文件对象,如下图,配置中默认加载的是FileMediaProfile,MediaProxySource_01对应Decklink卡的输入通道1,MediaProxySource_02对应Decklink卡的输入通道2,MediaOutputProxy_01对应Decklink卡的输出通道3。此处用到的是“媒体代理文件”的知识点,最终目的是为了在同一场景中适用不同的视频通道卡,比如说我还要用到AJA的视频卡,只需要再新建个媒体描述文件(MediaProfile),在媒体描述文件中指定AJA的输入输出(跟Decklink卡配置类似),场景中调用AJA相关的媒体描述文件,不需要在修改其他配置。当然,如果我们只有BMD的Decklink卡,就不需要媒体描述文件,也不需要用到媒体代理,只需要直接实例化Decklink的输入输出对象即可。


MediaProfile

MediaProxySource_01、MediaProxySource_02、MediaOutputProxy_01具体文件路径在Content->VirtualSet->Media目录下,文件创建后是空文件,等待媒体描述文件往指定媒体代理文件中填入信号。在回顾下这三个输入输出文件具体放在场景的哪里?两个输入放入VirtualSetMediaInput1和VirtualSetMediaInput2,但需要依附在“媒体束”文件上,如下图VideoBundle_01和VideoBundle_2,“媒体束”文件相当于一块幕布,视频需要投影到幕布上才能显示,当然这块幕布的功能不止于此,后面再介绍;一路输出放入CameraSwitcher实例对象。


Media目录

视频输出文件和对象我们都指定好了,接下来要考虑把场景中的什么样的画面给输出,我们需要“虚拟摄像机”拍摄场景中的画面,还需要抓取(Capture)这些画面,然后给输出,具体配置在Window->DeveloperTools->Media Capture,如下图所示,配置在Media Viewport Capture选项下,因为只有一个视口输出,因此我们在视口下加入了两个摄像机对象VirtualSetMediaInput1Camera和VirtualSetMediaInput2Camera(在场景中能直接找到),一个输出对象MediaOutputProxy_01。如果想要测试视频输出状态,直接在Media Captre左上方,点Capture按钮,就能直接抓取“虚拟摄像机”信号并输出,如果需要在场景中使用,则需要在蓝图中调用对应方法,之前已做介绍。


Media Capture

最后编译Play->New Editor Window,两路切换如下,但是选中Enable Video Output选项打开输出时,会报Pixel Error的错误,也就是抓取分辨率跟实际输出的分辨率不匹配导致,网上查了好多没发现有人报这样的问题,没办法,只能自己解决。


CameraSwitcher切换显示

直接找到VideoOutput那段蓝图程序,在CameraSwitcher蓝图类->Enable Video Output,有个Capture Active Scene Viewport,该方法表示抓取有效视口输出,但是没有具体分辨率的设置,从函数内带的Capture Option输入引出选项Make MediaCaptureOptions如图,勾选Resize Source Buffer选项,再回到场景,重新编译Play,打开输出,成功实现,但是检查日志一直有丢帧的告警信息,也尝试过锁定输入输出同步,问题依旧,不知道是不是显卡的运算问题。


抓取视频匹配输出


输出丢帧告警

3.2.6、视频通道抠像

UE4说明文档上还有视频通道抠像的相关设置,此次也做了初步尝试,笔者重新做了一个场景,Decklink输入1选择带绿箱的演播室视频,输入2选择开窗。MediaBundle在实例化对象时,会在对应目录新建MediaBundle1_InnerAssets目录,点进目录并打开MI_MediaBundle1文件,Details面板显示如图,可通过EnableKeyer打开抠像键功能,对此通道内的视频进行抠像设置,具体抠像参数不做复述,跟传统广播电视中的抠像原理一致,另外一张图是笔者测试的抠像显示输出情况,Alpha通道没扣干净,凑合着测试用下。


MI_MediaBundle


视频合成抠像

四、总结

UE4确实在广电应用上提供了一个很好的案例供参考,但是距离更多的应用需求,如AR、VR、4K包装输出等,目前还找不到很好的参考例子,国内外厂家也都在这块继续做深耕探索,之前来我台做过案例暂时的Zero Density,就是运用了UE4,加入自己开发的跟踪和抠像,实现了很好的输出效果,我仅谈一下自己对这块的理解和看法。

1、AR、VR应用——UE4在手机和平板端有ARKit和ARCore两大开发包支持,很方便就能实现AR的输出,但是广电的AR应用又是另外一块,需要结合的是摄像机机器人的位置参数、Zoom和Focus值,比较典型的协议有freed和telemetrics,如何将这些协议放入UE4,将实际摄像机位置和虚拟摄像机进行重叠,把视频信号作为背景,场景信号作为前景,都有值得研究的方向;VR应用则更需要抠像算法上的升级,测试中使用自带的视频通道内抠像,还是遵循着老的一套抠像原理,选取指定颜色进行扣除,存在着扣不干净或者扣太深的情况。VR目前看上去,Zero Density结合UE4的抠像确实做的不错,颠覆了以往的抠像方式。

2、4K包装输入输出——视频通道卡也得做升级,目前暂时只支持HD输入输出,BMD和AJA都有自己的SDK开发包,可以结合实际需求,对SDK开发包进行修改,开放对应的蓝图选项功能,或者等待厂商的发布(UE4商城上更新确实比较慢)。

3、广电的实际应用——离不开的话题就是新闻演播室节目包装的制作,业内很多人会拿Vizrt、Orad跟UE4做比较,我觉得有些人可能过分妖魔化UE4了。首先,我的理解是,UE4就好比一堆高档的食材,新闻演播室的包装就是快餐产品,你拿鲍鱼海参放KFC里面制作,又要让它好吃,又要做的快,这很矛盾,很多人也不会这么做。Vizrt和Orad可能是做“新闻快餐”里面最符合广电人口味的,播控和文稿结合成熟,操作方便,场景制作门槛也不算太高,关键用到的编程不需要太复杂。新闻美编不会去关注这个场景的材质,光影效果,毛发效果,真实感,他们可能最关心的是我怎么把这个模型做出来放到Vizrt里面播出来,然后不要太占用资源,场景能炫一点最好。那么结果就是你让新闻美编去用UE4,其实跟用Vizrt是一样的,至少看上去的做出来的东西一样的。

所以扯了那么多,UE4还能在广电用吗?当然能,它需要的是一些真正愿意去做精品,做专题的人去实现(好的厨师),可能需要一个团队,像游戏开发一样,场景、故事脚本、逻辑设计、程序实现、后期推广等等。

你可能感兴趣的:(Unreal Engine4入门及广电应用探索)