☰
grandMA2onPC与UE4灯光:DMX/Art-Net链路排查实战
2026/9/30 10:37:59 网站建设 项目流程

1. 先把这条链路讲清楚:MA 的数字信号是怎么变成 UE 里那盏灯的亮度的

grandMA2onPC 控制 UE4 灯光,本质上是把一个灯光行业用了三十年的控制协议,塞进实时渲染引擎的蓝图里。你在 grandMA2onPC 里推一个推杆,控台把数值写进某一根 DMX 通道,通过网线以 Art-Net 广播出去;UE4 这边的 DMX 插件收到包,把对应的通道值解出来,交给蓝图去驱动 Point Light 的 Intensity、材质参数、或者一个摇头灯模型的旋转。整条链路里没有任何"神秘"的东西,每一个数值都能被追溯、被抓包验证,这也是我偏爱这套方案的原因——出问题的时候你有地方可查。

很多人第一次接触这个组合是在虚拟演播室、虚拟演唱会或者灯光预演(previz)的项目里:导演希望先把灯位、cue 点、追光走位在引擎里跑一遍,确认效果之后再进场装台。也有人是拿 UE 当"便宜的 MA3D"用,一边在 onPC 上排 cue,一边在引擎里看真实材质和体积光下的效果。不管你是哪一种,只要涉及"用控台驱动引擎里的灯",你需要的知识是同一套:网络协议选型、universe 映射、通道表对齐、蓝图取值。

这篇文章不打算只给你几个菜单截图式的步骤。我会把每个环节"为什么这么做"讲透:为什么 DMX 比 OSC 更适合这件事、Art-Net 和 sACN 到底该选哪个、universe 的起始编号为什么总是差 1、8bit 的 DMX 为什么在引擎里看起来会抖。同时我会把我自己在项目里踩过的坑完整还原出来,包括那个让我查了两个小时的"只有第一个 universe 有数据"的问题。看完之后,你应该能做到:一台装了 grandMA2onPC 的电脑,一根网线,一台跑 UE4 的机器,从零把链路打通,并且知道断了之后该从哪一层开始查。

需要先说明一点:grandMA2onPC 的界面在不同版本之间菜单措辞会有变化,UE 的 DMX 插件在 4.25 之前基本不可用,4.26 之后才逐渐稳定成今天的样子。所以下文里的路径描述,如果和你屏幕上的字不完全一样,请按"功能"去找,而不是按"字面"去找。

1.1 为什么灯光预演这件事,DMX 比 OSC 和 MIDI 都合适

先说选型。用控台驱动引擎,能用的协议其实不止一种:DMX(Art-Net / sACN)、OSC、MIDI,甚至还有直接走 TCP 自己写协议的。但真正在灯光行业里跑得通的,只有 DMX 系。

原因很朴素。第一,grandMA2onPC 对 Art-Net 和 sACN 的支持是原生的、成熟的,你在控台上配接灯具、写 cue、跑 sequence,输出的就是标准的 DMX 数值,不需要任何中间转换程序。第二,DMX 的数据模型和灯光的思维方式完全一致:一个 universe 512 个通道,每个通道 0 到 255,一盏灯的每个属性占几个连续通道。这个模型和"灯具"这个概念是一一对应的,你在引擎里复现它,等于直接复现了现场的接线逻辑。第三,DMX 是广播式的、无连接的、丢包也不影响后续的,这一条在实时演出里极其重要——你不会因为丢了一帧就整个状态错乱。

OSC 的问题在于 grandMA2onPC 的 OSC 支持相对受限,能发的东西不如 DMX 全面,而且它是面向"消息"而不是"状态"的,你得自己维护状态同步,一旦丢包,引擎里的灯可能就停在某个错误的值上。MIDI 的问题更直接:7bit 精度、通道数量少、走 USB 还得额外驱动,一个摇头灯的 Pan Fine 就没法准确表达。所以除非你只是想让引擎跟着节拍闪一下,否则别绕这条路。

还有一个更"人话"的理由:DMX 是这个行业的通用语言。你今天用 onPC 驱动 UE,明天换成别的控台、或者要把同一份数据分给实体灯和引擎里的虚拟灯,通道表是共用的。这份资产是可以复用的,而自研协议不行。

1.2 Art-Net、sACN、MA-Net2 三条路,我在项目里怎么选

这三者都能承载 DMX,但适用场景差异不小,选错了会在现场吃大亏。

协议传输方式端口精度典型场景我的使用倾向
Art-NetUDP 广播64548/16bit小中型局域网、单交换机首选,配置最简单
sACN (E1.31)UDP 组播55688/16bit大型网络、多设备共享设备多、要跨交换机时用
MA-Net2MA 私有-高MA 设备之间同步只在纯 MA 生态里用

Art-Net 是广播,这意味着同一网段里所有设备都会收到包,配置上你几乎什么都不用做,填个 IP 就通了。缺点是设备一多,网络里全是广播包,交换机压力大,而且排查问题的时候不好定位是哪个源在发。sACN 是组播,需要交换机支持 IGMP snooping,配置门槛高一点,但它在多控台、多引擎的环境下更干净。

MA-Net2 是 MA 自己设备之间的同步协议,用来做多控台备份、NPU 扩展。它不直接对第三方软件输出,所以 UE 这边你不会去接它。

我的经验是:只要你的网络里只有一台 onPC 和一台引擎,Art-Net 就够了,别折腾 sACN。等你的项目里出现了两台控台、三台渲染机、一个像素映射服务器的时候,再考虑切 sACN,那时候网络规划也自然会跟上。顺便说一句,Art-Net 和 sACN 是可以同时在网络上跑的,端口不冲突,UE 的 DMX 插件也允许你同时启用多个协议,这一点在做"主备双路"的时候很有用。

1.3 universe 映射:那个永远差 1 的起始编号

这是全线里最容易出错、也最容易被忽略的一环。DMX 的 universe 是逻辑分组,你在 onPC 里看到的"Universe 1",和网络上 Art-Net 包里的"Port-Address 0",很可能指的不是同一个东西。

grandMA2onPC 的网络设置里有一个"Local Start"的参数,它的含义是:本地第一个 universe 对应到网络协议上的起始 universe 编号。如果你把 Local Start 设成 0,那么 onPC 里 patch 到 Universe 1 的灯,在 Art-Net 上是以 universe 0 发出去的。如果你设成 1,那就是 1 对 1,最直观。

UE 这边同理,Project Settings 的 DMX 配置里有"Local Universe Start"和 universe 数量。它的含义是:网络上传来的起始 universe,映射到 UE 内部的第一个本地 universe。所以如果 MA 发的是 Art-Net universe 0,而 UE 的 Local Universe Start 是 1,那么 UA 里的 Universe 1 就对应 Art-Net 的 universe 0;如果 UE 的 Local Universe Start 是 0,那就是原样对应。

我建议的固定做法是:两边都设成从 1 开始,1 对 1 映射。MA 侧 Local Start = 1,UE 侧 Local Universe Start = 1,然后所有 universe 数量都填够(比如 8 个)。这样你在控台上写的 Universe 3,在 UE 里就是 Universe 3,脑子不用换算,排查的时候也不容易搞混。别小看这一条,我见过太多次"数据在动但灯不对"最后发现就是这里差了 1。

顺便提醒一句:Art-Net 4 的 Port-Address 是 15 位,等于 Net(7位)× Sub(4位)× Universe(4位),一共 32768 个 universe。你在 onPC 里一般只会用到前面的 Sub 0、Universe 0 到 15 这一段,但如果你的项目里 universe 数量超过 16,就得留意 Net 和 Sub 的定义了,有些设备的界面上是分开填的。

2. 动手之前先定死三件事:IP 规划、universe 编号、通道表

链路调不通,八成不是软件问题,而是这三件事里有一样没提前定。我现在的习惯是,在开工程之前先在纸上把这三样写清楚,贴在显示器边上,后面所有配置都照着这张纸来。

2.1 网段与 IP:为什么 Art-Net 推荐用 2.x.x.x 或 10.x.x.x

Art-Net 的规范里明确建议在 2.x.x.x 或 10.x.x.x 这两个网段上运行,原因是避免和常见的办公网段冲突。这一条不是强制,但强烈建议遵守,尤其是当你的引擎机器同时还连着公司内网或者互联网的时候。

我的常规配置是:

  • grandMA2onPC 机器:IP 2.0.0.1,掩码 255.0.0.0
  • UE4 机器:IP 2.0.0.2,掩码 255.0.0.0
  • 直连一根网线,或者接一台不带管理功能的千兆交换机

掩码用 255.0.0.0 是 Art-Net 世界的习惯做法,好处是 2.0.0.1 到 2.255.255.255 全在一个网段里,你随便改 IP 都不会跑到网段外面去。用 255.255.255.0 也没问题,只是改 IP 的时候要留意第三段。

如果你只有一台电脑,想同时在上面跑 onPC 和 UE(做测试的时候很常见),那就需要一块虚拟环回网卡。Windows 自带的环回适配器在设备管理器里不太好装,很多人用第三方的虚拟网卡工具,或者干脆装一个"Microsoft KM-TEST 环回适配器"。给它配上 2.0.0.1,然后 onPC 和 UE 的网卡选择都指向它,Art-Net 广播就能在这台机器内部走通。这一步我踩过坑:直接往 127.0.0.1 发 Art-Net 有时候收不到,因为有些实现会过滤环回地址,用虚拟网卡配真实网段才稳。

另外两个必须做的网络动作:关掉所有无关网卡和 WiFi,以及在Windows 防火墙里给 UDP 6454 开入站放行。防火墙这一条太多人栽在上面了:UE 的 DMX Monitor 一片空白,查了半天插件配置,最后发现是防火墙把 UDP 包吞了。图省事的话,在测试阶段直接把专用网络的防火墙关掉,现场再逐条加规则。

2.2 先用一盏"只有 Dimmer"的灯把链路跑通

这一步是我强烈建议的流程。别一上来就把真实的摇头灯通道表导进去,先用最简单的东西验证链路:MA 侧配接一盏单通道的调光器(或者手工做一个 8bit 只含 Dimmer 属性的 fixture),UE 侧也做同样一个 fixture type,一个通道,属性名叫 Dimmer。

链路验证只需要三件事:

  1. onPC 里把 Universe 1 的 Channel 1 给到 100%。
  2. UE 的 DMX Monitor 面板(Window 菜单下,名字各版本略有不同,搜 DMX 就能找到)里,Universe 1 的 Channel 1 显示 255。
  3. 场景里一盏 Point Light 跟着亮起来。

这三步跑通,说明网络层、映射层、插件层全部正确,剩下的工作就只是"把通道表对齐"这件纯体力活了。如果这三步卡住,问题一定在前面三层的某一层,你可以按第 5 节的排查顺序来,不用瞎猜。

我之所以强调这个流程,是因为真实的摇头灯通道表动辄 20 到 40 个通道,还涉及 16bit 的 Pan/Tilt、色轮、图案轮、棱镜、聚焦,一旦链路本身有问题,你根本无法区分是网络不通还是通道表错位。用单通道先排除掉 80% 的变量,后面会省下大量时间。

2.3 通道表不对齐,后面全是坑

这是整个项目里最容易被低估的工作量。grandMA2onPC 用的是 MA 自己的灯具库,UE 用的是 GDTF(通用设备类型格式)或者你手工建的 fixture type,这两套东西的通道顺序默认不一定一致。

举个具体的例子:同一个型号的摇头灯,MA 库里的通道顺序可能是 Pan、Pan Fine、Tilt、Tilt Fine、Dimmer、Shutter、Color、Gobo;而某个 GDTF 文件里的顺序可能是 Dimmer、Shutter、Color、Gobo、Pan、Pan Fine、Tilt、Tilt Fine。这两个表在 DMX 层面上是"物理不同"的——你把 MA 的通道值按 GDTF 的顺序解,得到的会是完全错误的属性。

解决办法有三个,按我的推荐度排序:

  • 手工在 UE 里建 fixture type,严格按 MA 库的通道顺序排。工作量大,但绝对可控,不会出现"下次换了个人重新导 GDTF 就崩了"的情况。
  • 在 MA 里自定义 fixture type,按 GDTF 的顺序排。适用于你已经有现成 GDTF、并且现场不需要用 MA 物理控台去控这盏灯的场景。
  • 用 MA 的"DMX 视图"直接对通道,绕开属性层面的映射。最原始也最稳,代价是失去了属性级别的语义,后面蓝图里只能按通道号取值。

我一般用第一种。原因很简单:现场执行的人只认控台上的推杆和 cue,引擎这边是"服务方",应该迁就控台。而且 MA 库里现成的灯具类型最多,现场随手换灯也不会出问题。

需要补充一个细节:MA 的灯具库里同一个型号可能有多个"模式"(Mode),通道数不同的版本,比如一款摇头灯有 16 通道模式、24 通道模式和 32 通道模式。你在 MA 里选了哪个模式,UE 里就必须建哪个模式,通道数、顺序、属性类型都必须完全一致。这一步对不上,后面的排查会非常痛苦。

3. grandMA2onPC 侧:从打开 Art-Net 到把第一个值推出去

MA 这一侧要做的事情其实不多,但顺序不能乱。核心是两件事:先在网络设置里把 Art-Net 协议打开并指定起始 universe,再把本地 DMX universe 的输出指向 Art-Net 端口。这两步是"协议层"和"路由层",缺一不可。

3.1 在 Network 里启用 Art-Net 输出

打开 grandMA2onPC,进 Setup 菜单,找到 Network。在这个窗口里你要找的是和 DMX 协议相关的设置区块,通常会有 Art-Net 和 sACN 两个选项,以及每个协议下若干"端口"的启用开关。勾选 Art-Net,把起始 universe 设成 1(或者按你第 1.3 节的约定来),端口数量填够你的项目需要。

不同版本的 onPC 里,这个位置可能叫 Network Protocols,也可能直接就叫 DMX Protocols,还有的版本把它放在 Network 窗口的一个标签页里。名字不重要,你只要找到"哪个协议、从哪个 universe 开始、一共开几个"这三件事就行了。

这里有一个容易被忽略的点:onPC 的网络设置里可能会让你指定使用哪块网卡。如果你机器上有多个网卡,一定要选到接了那根网线的、配了 2.0.0.1 的那一张。选错了,包会从另一块网卡发出去,UE 那边永远收不到。这个坑我在现场遇到过,当时机器上插着一条内网网线,Art-Net 包全跑到内网去了。

3.2 把本地 DMX universe 的输出指向 Art-Net

协议打开了,还得告诉 onPC"哪个 universe 从哪个口出去"。这一步在 DMX Universes 相关的列表里做,你会看到每个本地 universe 都有一栏输出端口的设置。把 Universe 1 的输出选成 Art-Net 1,Universe 2 选成 Art-Net 2,以此类推。

有一个我踩过的细节值得说一下:如果你的工程是从别人那里拷来的,或者是在有物理控台的配置里改的,universe 的输出可能还指向物理 DMX 口或 MA-Net。这时候你在 onPC 上推推杆,控台界面上看得到数值在变,但网络上什么都没有。所以每次新接项目,我都会花一分钟检查这个列表,确认输出端口是 Art-Net 而不是别的。

另外,DMX Universes 里还有个"合并"(Merge)相关的设置。在极少数场景下你会需要把两路 DMX 合并到一个 universe(比如主备控台),那就要注意 HTP(取最大值)和 LTP(取最新值)的区别。灯光行业默认是 HTP,但在虚拟灯光预演里,如果你希望引擎严格跟随某一台控台,LTP 可能更符合直觉。这个顺序不能错,否则两路信号叠在一起的时候会出现奇怪的值。

3.3 配接灯具,用命令行走一个值

协议和路由搞定之后,就是配接。在 onPC 里新建一盏灯,选好型号和模式,patch 到 Universe 1 的 Address 1。然后就可以用命令行直接给值了。

我习惯用最直接的方式验证:

  1. 命令行输入灯的编号,按 At,输入 100,按 Please。也就是"给这盏灯的所有属性设到 100%"。
  2. 打开 DMX Sheet(DMX 视图),找到 Universe 1,看 Channel 1 是不是 255。
  3. 如果这里在动,说明 MA 侧的输出完全正常,问题在网络上或者 UE 侧。

这个顺序很重要:先在控台内部验证,再验证网络,最后验证引擎。很多人一上来就在 UE 里翻配置,其实控台自己都没输出,白折腾。

补充一个实用的操作习惯:在 onPC 里建一个"测试用 Executor",放一个 Chase(追逐)或者一个简单的 Sequence,让它自动在几个值之间来回跑。这样你在 UE 那边调试的时候不用一直手推推杆,数据会自己动,看起来更直观。我甚至会用速度参数把它跑到 1 秒一个循环,这样 DMX Monitor 上的数值变化用肉眼就能看出来。

3.4 onPC 免费版的输出限制,这件事必须先算清楚

这一点必须提前说清楚,不然你会陷入"数据看起来在动,但只有第一个 universe 有值"的困惑。

grandMA2onPC 是免费的,但免费版本在参数数量和网络输出 universe 数量上是有上限的,超过上限的部分需要接入 MA 的硬件(比如 command wing、fader wing、NPU 之类)才能解锁。这个上限具体是多少,不同时期的授权政策会有调整,我不在这里给死数字,你在项目开始前一定要去官方当前的授权说明里对一遍。

这个限制在灯光预演场景里影响是这样的:如果你只有一盏灯、几个通道,完全没问题;但如果你要跑一整个舞台的 20 盏摇头灯加 40 台 LED 染色灯,参数很可能超。所以我的建议是:

  • 项目开始前先算参数总量,灯具数量乘以每台的通道数,再加上余量。
  • 如果超了,考虑只把"引擎里需要看见"的那部分灯接进 DMX,其余的在控台上不上电。
  • 或者用多条 universe 分散,但要先确认你的授权允许输出这么多 universe。

还有一种变通做法:不用 onPC 的完整配接,直接在 MA 里用一个"DMX 通道直出"的方式,绕开灯具配接的参数计算。这种方式精度低、语义差,但验证链路的时候够用。

4. UE4 侧:插件、DMX Library、Patch 与蓝图取值

UE 这边是工作量最大的一块。DMX 插件在 4.26 之后逐渐成型,主要包含几个部分:DMX Engine(核心)、DMXProtocolArtNet / DMXProtocolSACN(网络协议)、DMX Fixtures(灯具配接与属性)。如果你用的是更早的 4.x 版本,官方插件可能不完整,那时候大家用的是社区的 Art-Net 插件,逻辑类似但 API 不同。下面讲的是 4.26 及以后的路径。

4.1 开插件与 Project Settings 里的 DMX 配置

先开插件:Edit → Plugins,搜索 DMX,把 DMX Engine、DMXProtocolArtNet 打开(如果你的网络用 sACN,就把 DMXProtocolSACN 也开上),再打开 DMX Fixtures。改完要重启编辑器。

重启之后进 Project Settings → Plugins → DMX,这里有几个区块需要填:

  • Communication Settings:Protocol 选 Art-Net,Network Interface Card 选你配了 2.0.0.x 的那块网卡。它下面还有个输入端口,Art-Net 默认是 6454,一般不用改。
  • Universe Settings / Input Settings:这里就是前面说的映射。Local Universe Start 填 1,Num Universes 填你实际用到的数量(比如 8)。
  • Art-Net 相关设置:如果有"起始 universe"之类的字段,按第 1.3 节的约定填 1。

配置完之后,最快验证方式是把 UE 的 DMX Monitor 面板打开(在 Window 菜单下面,各版本入口不一样,搜 DMX 就行),看 Universe 1 的通道值有没有跟着控台动。如果这里有值,说明网络层和映射层全对,剩下的都是应用层的事。

有一点要提醒:改完 DMX 的网络配置之后,最好重启一次引擎。这两个插件在编辑器启动时初始化网络监听,热改配置有时候不会立刻生效,会让人误以为配置不对。

4.2 建 DMX Library,手工定义 fixture type

在 Content Browser 里右键,找 DMX 分类,新建一个 DMX Library。这是所有灯具配接的容器。

接下来是定义 fixture type。这里有个分岔:

  • 导入 GDTF:如果你的灯具型号在 GDTF 库里有现成的,导入最省事。但要按第 2.3 节检查通道顺序和模式是否和 MA 库里的一致,不一致就得手工改。
  • 手工新建:在 DMX Library 里新建 fixture type,逐个添加属性。属性需要设名称(比如 Dimmer、ColorAdd_R)、数据类型(8bit / 16bit / 24bit)、默认值。这一步很枯燥,但做一次可以复用很久,我建议第一次就做仔细,把常用灯具都建好,存成一个"工程模板"。

属性命名这件事值得多说两句。UE 里有内置的标准属性名(Dimmer、Pan、Tilt、ColorAdd_R/G/B、Shutter 等等),蓝图里取值时用的就是这些名字。如果你在 fixture type 里把属性叫成"Dimmer2"或者"DIM",蓝图里就得用这个名字去取,GM2 那边的属性名再怎样都不会影响 UE,因为 DMX 层只认通道号,不认名字。所以命名完全可以按你自己的规范来,只要在蓝图里保持一致。

我自己的命名习惯是直接用 UE 的标准名,这样跟官方文档、示例工程、以及网上大多数教程都对得上,减少沟通成本。

4.3 Patch 到与 MA 完全一致的宇宙和地址

fixture type 建好之后,在 DMX Library 里新建 fixture patch,指定用哪个 fixture type、patch 到哪个 universe 的哪个起始地址。这个地址必须和 MA 里一模一样。

我一般会做一张对照表,长这样:

MA 灯具编号灯具类型/模式MA UniverseMA AddressUE UniverseUE Address通道数
1Spot 32ch Mode3111132
2Spot 32ch Mode313313332
3Wash 24ch Mode216516524
.....................

这张表看起来笨,但它能在排查的时候救你的命。当 UE 里第 5 盏灯不动的时候,你可以直接对照这张表去查 MA 的 Universe 1 Address 之类有没有输出。

一个常见的坑是地址重叠:如果你在 UE 里 patch 的时候忘了算上一盏灯的通道数,两盏灯的地址区间叠在一起,后面那盏就会读到前面那盏的通道,表现为"两盏灯同时动"。这种问题看 DMX Monitor 是看不出异常的,只能靠对照表逐条核。

4.4 蓝图里读属性:Dimmer、Color、Pan/Tilt 的具体实现

这是最有意思的一步。建一个 Actor Blueprint,里面放上你要驱动的组件:Point Light、Spot Light、静态网格体(当作灯具的灯体)、还有 DMX Fixture 组件(来自 DMX Fixtures 插件)。DMX Fixture 组件上要挂上刚才 patch 的那个 fixture patch。

然后是蓝图逻辑。DMX Fixture 组件会提供一个 On DMX Updated 事件,以及 Get Normalized Attribute Value 这类取值节点(不同版本名称略有差异,搜索 DMX 都能找到)。整体思路是:事件触发时,把每个属性值取出来,映射到你要驱动物理量上。

具体到三类最常见的属性:

Dimmer(亮度):取值是 0 到 1,乘上你设定的最大亮度(比如 8000 流明),直接 Set Intensity 给 Point Light 或者 Spot Light。这里建议用 Set Intensity 而不是改组件的相对亮度,因为 DMX 送来的本身就是绝对值,直接设更符合直觉。

Color(颜色):ColorAdd_R、ColorAdd_G、ColorAdd_B 三个属性各取一个 0 到 1 的值,Make Linear Color 之后 Set Light Color。注意 MA 的混色值是线性 DMX 值,而引擎里的光照计算是在线性空间里的,所以直接映射是合理的,不需要做 gamma 校正。但如果你希望"推杆的手感"更接近实体灯,可以考虑在取值之后加一个曲线(Curve Float)做非线性映射,因为人眼对亮度的感知是非线性的。

Pan / Tilt(摇头):这两个属性通常用 16bit,取值后映射到角度范围。比如 Pan 从 -270 到 270 度,Tilt 从 -135 到 135 度,用 Lerp 映射之后 Set Actor Rotation(Pan 对应 Yaw,Tilt 对应 Pitch)。这里需要一个父级 Actor 承载整个灯具,让灯体和灯光一起旋转,而不是只转灯光组件。

一个实战的写法建议是:把每个属性的处理拆成独立的函数或宏,比如 UpdateDimmer、UpdateColor、UpdateMovement,然后用 Sequence 串起来。这样后面加属性的时候不用动主逻辑,改一个函数就行。蓝图一大团的话,维护起来会非常痛苦。

4.5 8bit 抖动与 16bit 精度:为什么引擎里的灯看起来在"抽"

DMX 的通道值是 0 到 255,8bit。这个精度在实体灯上不明显,因为灯泡本身有惯性、有调光曲线,人眼也不敏感。但放到引擎里,尤其是驱动一个高亮的 Spot Light 亮度、或者肉眼看得很清楚的角度旋转时,8bit 的阶梯感会非常明显——推杆缓慢移动的时候,灯光会一跳一跳的。

解决办法有三个,我一般组合使用:

  • 用 FInterpTo 或 RInterpTo 做插值。在 Tick 里把当前值和目标值做插值,让过渡平滑。插值速度设成 6 到 10 左右比较合适,太快了等于没做,太慢了会有明显延迟。这是最通用的一招。
  • Pan/Tilt 用 16bit。在 fixture type 里把这两个属性定义成 16bit,MA 那边输出 coarse 和 fine 两个字节,UE 这边会合成一个更精细的值,角度就不会一格一格跳了。
  • 颜色做曲线映射。ColorAdd 三个通道各 8bit,在低亮度区域分辨率特别差,加一条曲线把低段拉开,视觉上会好很多。

顺便提一句,DMX 的发送频率一般是 40Hz 左右,但 UE 的 Tick 可能是 60Hz 或 120Hz。也就是说 DMX 数据每秒只更新 40 次,但你的蓝图每秒跑 60 次以上,会出现"同一个值被连续读好几次"的情况。这不影响正确性,但如果你在 Tick 里做累加之类的操作,要记得乘 DeltaTime,别写成每帧固定增量。

还有一个性能上的注意点:不要在 Tick 里反复遍历所有灯具的所有属性。如果你的场景里有几十盏虚拟灯,正确的做法是让每个灯具的 Blueprint 自己处理自己的事件,而不是搞一个总控蓝图去轮询。UE 的 DMX Fixture 组件本身就会分发对应 patch 的更新事件,用它是最省事的。

5. 链路不通时的完整排查顺序:从抓包到下位数据

这套系统出问题的时候,症状往往很模糊:"灯不动"。但"灯不动"可能的原因有十几层。我总结了一套从下往上的排查顺序,基本能在十分钟内定位到具体层级。

5.1 第一步:确认 onPC 内部真的有输出

先别看 UE,先看控台。在 MA 里打开 DMX Sheet,或者在 Channel Sheet 里看通道值。给灯一个明确的值(比如 At 100),看对应的通道是不是 255。

如果这里不动,问题在 MA 侧,跟 DMX 无关:可能是灯具没配接、地址错了、或者被 Group / Preset 覆盖了。这种情况先解决控台内部逻辑。

如果这里在动,说明 MA 已经算出了 DMX 值,接下来才轮到"值有没有发到网络上"。

5.2 第二步:用抓包确认包到底发出来没有

这一步我用的是 Wireshark。在 UE 的机器上装一个(或者用另一台笔记本接在同一交换机上),过滤 udp.port == 6454,然后推一下控台的推杆。

正常情况下你会看到一串持续的 UDP 包从 2.0.0.1 发往 2.0.0.255(广播地址)。点开任意一个包,在数据部分能看到明文头 "Art-Net",后面跟着 OpCode、Protocol Version、Sequence、Physical、SubUni、Net、Length 这些字段。SubUni 和 Net 加起来就是那个包的 universe 编号。

这一步能一次性排除掉三类问题:

  • 完全没有包:MA 侧没输出,或者网卡选错了,或者交换机/防火墙拦了。
  • 有包但 universe 号不对:映射配置错了,回到第 1.3 节重新对。
  • 有包但只有第一个 universe:大概率是 onPC 的输出上限,回到第 3.4 节。

我强烈建议每个做这套系统的人都学会看 Art-Net 包。这个技能一旦掌握,你会从"猜问题"变成"看问题",效率完全不同。

5.3 第三步:UE 收到了没有

抓包确认有包之后,回到 UE。打开 DMX Monitor,看对应 universe 的通道值有没有动。

如果不动,可能的原因按概率排序:网卡选错了(UE 的 NIC 设置指向了别的网卡)、universe 映射偏移、防火墙拦了入站、或者插件配置改了没重启。这四个我都在项目里遇到过,其中网卡选错是最常见的。

还有一个小概率情况:你的 UE 机器上有多个网卡,且都在同一网段。这时候 Art-Net 广播会从其中一个发出、从另一个进来,UE 的接收可能绑在有线网卡上但你的发送走的是 WiFi,导致收不到。解决办法就是第 2.1 节说的,关掉无关网卡。

DMX Monitor 里有值之后,网络层就彻底没问题了,剩下的都是应用层。

5.4 第四步:有值但灯不动,问题在 patch 或属性名

这时候要查三件事,按顺序:

  1. fixture patch 的 universe 和地址对不对,跟第 4.3 节的那张对照表逐条核。特别注意地址有没有重叠。
  2. DMX Fixture 组件上挂的 patch 是不是你想要的那个。我遇到过在一个 Actor 里挂错了 patch,结果这盏灯跟着另一盏灯动的情况。
  3. 蓝图里取的属性名,在 fixture type 里是不是真的存在。如果属性不存在,取值节点会返回 0 或者默认值,灯当然不动。这个错误在蓝图里不会报错,只能靠核对。

还有一个隐藏得很深的情况:attribute 的字节序问题。16bit 属性在 DMX 上是 coarse 在前、fine 在后,如果你的 fixture type 定义成了 24bit,或者字节数填错了,取值会把后面一个属性的通道也吃进去,表现为"这盏灯跟着旁边那盏灯一起动"。这种情况只能靠仔细核对手工建的 fixture type。

5.5 第五步:数据对但看起来不对,通常是精度和映射曲线

如果链路全通、patch 正确、属性也在动,但视觉效果和现场感觉差很远,那问题不在"通不通",而在"像不像"。常见的有几种:

  • 亮度曲线不对:DMX 是线性的,人眼是非线性的。实体灯出厂时自带调光曲线,引擎里没有,你得自己在蓝图里加曲线。
  • 颜色偏:MA 的三原色混色和引擎的 Linear Color 在色域上不完全等价。想要更接近可以用色轮的角度值,但 MA 发的是 RGB,需要转成 HSV 再映射到色轮位置。
  • 摇头速度不对:实体灯有电机加减速,引擎里是瞬时的。给 Pan/Tilt 加 RInterpTo 就是在模拟这个惯性。
  • 闪烁(Strobe)不对:DMX 上的 Strobe 是一个 0 到 255 的连续值,表示频率。你需要在蓝图里把它映射成一个定时器频率,值越大闪得越快,同时要处理"0 表示常亮、255 表示最快"这种两端特殊定义。

6. 在真实项目里我怎么组织这套流程

前面都是技术细节,这一节讲一点工程组织上的经验,因为这些往往比技术本身更影响项目能不能顺利交付。

6.1 一份"链路文档"比什么都有用

每次做这类项目,我都会在工程根目录放一个 markdown 文件,里面写清楚:网段规划、IP 分配、universe 映射约定、灯具配接对照表、fixture type 的命名规范、以及 DMX 插件的关键配置截图。

这东西在项目开始的时候花你半小时,但在后面节省的时间可能是十倍。因为灯光预演这类项目通常涉及两拨人——控台那边的人和引擎这边的人,两个人的脑子里的"Universe 1"可能根本不是一回事。有一份文档,沟通成本立刻下降一个量级。

而且这份文档是可以复用的。做第二个类似项目的时候,直接把网段和 universe 约定搬过去,只改灯具对照表就行。

6.2 用 Git 管理 DMX Library 和蓝图

UE 的 DMX Library 是一个资产(asset),它和蓝图一样可以进版本控制。我强烈建议把 DMX Library、所有灯具蓝图、以及那份链路文档放进同一个仓库,和场景资产一起管理。

原因很实际:灯具配接表是会被改的,控台那边换一款灯、换一个模式,引擎这边就得跟着改。有版本控制你能知道谁在什么时候改了什么,而不是对着一个"昨天还好好的"的工程发呆。

另外建议把 DMX Library 做成"一灯一文件"的结构,而不是所有灯都挤在一个 Library 里。这样合并冲突的概率会小很多。

6.3 用序列帧录制做离线的视觉校验

DMX 是实时的,有时候你需要在没有控台的情况下反复看效果。我的做法是在引擎里搞一个"回放模式":把一段时间内收到的 DMX 通道值全部录成一个快捷方式(或者干脆用引擎的 Take Recorder 录一段),然后离线回放。

具体做法是在 DMX 更新事件里把每个属性值写进一个 buffer,加上时间戳,录成一张表。回放的时候按时间戳插值输出。这个功能做一次可以复用很久,尤其是在给导演看效果的时候——你不需要把控台搬过来,放一段录像就行。

需要注意的是,录制的采样率和 DMX 的发送率要对齐,不然插值出来的曲线会失真。我一般按 40Hz 录,和 Art-Net 的发送率一致。

6.4 现场备份:控台出问题的时候引擎该怎么办

灯光预演虽然是"预演",但很多时候是给导演、给客户看的,不能中途黑屏。所以我在每个项目里都会准备一条备份路径。

最常见的是双路输入:MA 一路 Art-Net,另一路是一个简单的 MIDI 控制器或者一个 UDP 脚本,一旦主路断了,引擎里的灯具切换到一个"安全状态",比如保持当前值、或者缓慢过渡到一个固定的演出状态。UE 的 DMX 插件里可以同时启用 Art-Net 和 sACN,也可以在主数据停更超过一定时间之后触发 fallback 逻辑,这个在蓝图里用一个 Timer 就能实现。

还有一个更简单的做法:在引擎里内置一套"演示模式",断开网络的时候自动跑一段本地动画。这样即使控台挂了,客户看到的也不是一片黑。我一般把这个开关做在关卡蓝图里,按一个键就能切换。

我自己在实际项目里踩过最狠的一次坑,是控台和引擎不在同一个网段——控台那边为了连内网把 IP 改成了 192.168.x.x,UE 这边还写着 2.0.0.2,广播根本发不过去。那一次的教训是,任何一次 IP 变更都要回头对一遍那份链路文档。还有一次更隐蔽:onPC 的网络设置里网卡选错,包从另外一块网卡出去了,用 Wireshark 一抓立刻现原形,但如果不抓包,你可能会在 UE 的插件配置里白白折腾一个小时。所以,把抓包当成排查的第一步,而不是最后一步,这是我做了几个项目之后最实在的一条心得。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询