介绍
有一天我在学习制作UE场景特效的时候突发奇想,这么多炫丽的效果只能在游戏里看到实在太可惜了,怎么样才能使他们在Web应用里头发光发热,后来随着学习进一步深入发现UE在影视、建筑、电商等行业也有大量的应用场景,因此也是支持导出高质量的视频或者图片的。于是经过几天粗浅的探索,就有了本文的实现思路。
目前主流浏览器中支持alpha透明通道的动态图片格式有apng和webp(apng出生早,有更广泛的适用度,webp有更好的压缩技术,能够进一步缩小文件体积),UE特效在Web开发的应用就是导出这两种图片应用到场景中。
应用场景
-
用粒子系统模拟现实效果
镜头暴风雪
工厂烟囱
广场烟花效果
-
制作带特效的POI
-
大屏组件的动效点缀
萤火虫粒子效果
使用工具
- UE 4.26:用于制作效果
- UE插件MovieRenderQueue:用于将效果渲染并导出为序列图格式
- Adobe After Effect(AE): 用于将序列图转换为最终文件,导入文件格式为exr
- APNG在线合成下载工具: 作用与AE相同,导入文件格式为png
- Honeycam : 这是1个截屏生成动画软件,用于再次处理动态图,比如裁剪,压缩,剪辑,转换格式等
操作步骤
-
在UE中制作好特效内容,设置好录制摄像机CameraActor
-
将需要渲染的对象放到同一个图层exportLayer
-
创建关卡过场序列Seq,将CameraActor拖入Seq中,设置好动画时间
添加序列
-
打开"影片渲染队列",调整输出和设置,具体教程看附件链接《Media Render Queue使用技巧》,点击本地渲染就可以直接输出序列图。我们一般会用到3种图片格式jpg、png和exr,正常情况下jpg就够用了,png支持alpha通道,即半透明图片,而exr则是用于导入到AE中继续处理。
-
使用图片生成工具将序列图转为apng,本文使用的是 APNG在线合成下载工具。 如有必要,使用Honeycam给图片继续做裁剪,压缩体积导出webp格式。
-
在地图中创建自定义点标记
jsx
// 三种点标记形式
const markerStyleMap = {
// 锥体
'poi_3d_1':{className: 'warn-ico',width: 100,height: 128, altitude: 0,},
// 光柱
'poi_3d_2':{className: 'warn-ico',width: 100,height: 100, altitude: 0,},
// 烟花
'poi_3d_3':{className: 'warn-ico',width: 200,height: 190, altitude: 50,}
}
function addMarker({lng,lat,type}) {
const {className,width,height,altitude} = markerStyleMap[type]
let marker = new AMap.Marker({
content: `<div class="${className}" style="width:${width}px;height:${height}px;"><img src="./image/${type}.webp"/></div>`,
position: [lng,lat,altitude],
offset: new AMap.Pixel(-width/2, -height+8)
});
marker.setMap(map);
}
把自定义点标记图层的容器标签增加css
css
.amap-markers{
// 图片为黑色背景,需要与父元素做融合,有点类似正片叠底
mix-blend-mode: screen;
}
.warn-ico{
// 该声明可以直接修改内容的整体色调,创建多种颜色类型
filter: hue-rotate(45deg);
}
然后效果就做出来了
方案优点
- 上手简单粗暴,最复杂的问题已经在转换成图片之前解决了,对外输出都是一张序列图片,只管用就行。
- 适用范围广,比如做一个酷炫的loading,只管堆效果,只要浏览器支持apng、webp图片格式就行,不用考虑兼容性。
方案缺点
- 序列图片的内存开销与数量强关联
打开性能监测选项,可以发现在每次点击鼠标增加动态告警标记点的过程中,内存消耗一路上升,这代表着就算是同一个图片,只要增加一个实例就会多增加一份消耗,这意味着该方法不适宜数量级庞大的应用场景。
那么有没有办法能规避这种问题?当然有,就是使用webGL图层,把图片效果变成纹理贴图贴到three.js网格模型中,再用instancedMesh的办法将模型实例化,就可以在保证性能的前提下创造大量模型实例
2.图片仅适用特定视角
序列图片本质上还是一张特定角度的二维图片,一旦调整场景角度到极值就会因视角不统一让画面看起来别扭。解决办法要么就是限制角度范围,那么就是彻底3D化。
待解决问题
UE作为游戏引擎,硬要把它用来渲染处理序列图,实属有走旁门左道,因此在渲图方面还是有一些瑕疵的。
比如某些半透明发光材质,使用UE插件MovicRenderQueue渲染导出alpha透明通道,会有颜色丢失问题,导致整个物体看上去很黯淡,好像只渲染了一个颜色通道。
目前除了把黑色背景一并渲染出来,我还找不到有效的解决方法,也许以后通过一些额外的插件或设置可以解决。
虽然在处理特效方面有其他更加专业的工具,比如AE啥,但在这里使用UE顺便给Web提供特效其实一鱼两吃的做法,视频和图片只是实现过程的副产品,节省了一些工作量,今天就到这里吧。