动画|趣加互娱首席特效专家张韶勇GDC2022演讲:数学在特效制作中的重要性
文章图片
对于移动游戏的特效艺术家来说 , 大多时候的创作环境是这样的:“产品需要好的视觉效果 , 但是给到特效师的创作时间十分有限 。 ” 因此 , 大多数的特效艺术家没有时间为VFX创造自己的贴图资源 , 特别是序列帧 , 更不用说去弄明白复杂的Flow-map Shader了 。 怎样才能在最短的时间内获得特效需要的高质量的序列帧贴图呢?即时流体模拟插件FluidNinja是一个最好的选择 。
文章图片
FluidNinja是Unreal Engine中的一款高质量的特效制作插件 , 特效师可以依靠插件的强大的算法 , 在短时间内模拟火、水、烟、爆炸、魔法等各种流体效果表现 。 它可以通过粒子系统、位图 , 动力场等输入方式创建我们想要的像素动画 。 接下来我们将讲解具体的制作过程 。
首先 , 我在3D Max中制作3D字母“GDC” , 将其颜色设置为黑白 , 渲染并保存为jpeg格式图像 。
文章图片
文章图片
接下来 , 我将这个字母图像导入到FluidNinja中 , 通过调整Amplify、Turbulence、Curl Scale等值 , 来获取我想要的火焰运动形式、速度和色彩 。 然后烘焙并导出2张不同的图像:密度图与速度图 。 其中 , 密度图是火焰的形状和颜色 , 而速度图则记录了像素的运动方向和速度 , 因此 , 我们也把速度图称之为流程图(Flow-map) 。
文章图片
这里左边是导出的流程图 , 右边的是密度图 。 (这里只展示了序列帧其中4格)这两张图都是HDR格式 。 由于大部分移动游戏使用Unity开发 , 但Unity并不支持HDR的图像格式 。 所以我们需要用一些图形转换工具 , 将HDR图像转换为TGA图像 。 Google 一下“HDR to TGA", 就可以网上进行转换 。
这个模拟火焰燃烧的VFX看起来非常棒 , 而且几分钟就完成了 。 但它还必须便宜 。 手游戏中的贴图大小和贴图数量必须在控制在有限的范围内 。 在这种情况下 , 火焰的图像序列不能大于1024x1024像素 。
文章图片
在1024x1024像素的图片序列中 , 如果每个单元格是256x256像素的话 , 那么我们总共只有16帧去表现特效动画 。 16帧的特效在手游上只能停留大约半秒的时间(手游大多数产品的标准帧率是30帧/秒) , 但很多特效需要持续几秒时长 。
我们也可以选择将单元格的大小设置为128x128像素 , 这样我们就可以获得64帧的效果 , 但是在这种情况下 , 每一帧的图片质量都会成倍降低 , 而这并不符合大多数情况下产品预期的图像质量标准 。
我们是否可以通过添加中间帧的方式 , 在不增加图像大小的前提下 , 使当前总帧的翻数倍呢?yes , 我们可以使用像素动画和流程图(Flow-map)来解决这一问题 。
文章图片
在FluidNinja中 , 其中一种方式是利用粒子系统作为输入源来生成像素动画 。 它的算法像是CFD , 这个我不懂 。 但从视觉上来看 , 就是黑色背景与白色粒子之间的空间和密度影响了最终的运动效果 。 我们可以调整粒子的大小、数量和速度来获得不同效果的流体运动效果 。 在这个案例中我们使用了更简单的位图作为输入方式来制作“GDC”图形上的火焰 。
文章图片
在获得序列帧贴图资源后 , 将流程图和密度图导入Unity粒子系统中的Amplified Shader Editor材质中 。 这样就获得了一个高质量、高流畅度的GDC火焰动画 。
我们还做了一件事 , 就是简化Flow-map Shader 。 因为FluidNinja所提供的Shader更适合家用机游戏 , 然而我们希望它在移动设备上顺畅运行 。
文章图片
这是在Unreal Engine中的Flow-map Shader , 它一共有114个节点 。 这么多节点对于移动平台来说过于复杂 , 我们需要将其简化到原数量的1/3以下 。
在这一点上 , 其实没有多少特效艺术家会有耐心和时间去研究这些Shader , 太复杂了 , 我理解 。 所以 , 我们先从原理开始 , 通过一些简单有趣的案例来了解FlowMap运作基本原理 。
咦 , 我怎么被扭曲了?-在这个Shader中我导入了一张自己的照片 , 并将这张照片的纹理在通常的笛卡尔坐标系和极坐标系之间切换 。 在切换坐标的同时 , 图像像素的位置发生了变化 。
文章图片
可以看到 , 当我们挪动滑杆时(Lerp , 差值变化) , 我的照片随着数值增长 , 产生了扭曲效果 。 这个简单案例告诉我们:制作像素动画其实就是操纵像素的位置与坐标 。
如果我们利用一张图代替这个极坐标节点会发生什么呢?对特效师来说 , 这意味着自由!因为我们可以根据自己的想法 , 自由的画出图像的运动趋势 。 对 , 我们可以画出运动!
让我们来看下一个案例 。
文章图片
文章图片
现在 , 在FlowMap Shader中 , 将我的照片替换成GDC贴图 , 同时将极坐标节点替换为了一张flow-map图 。 这张图是我在Photoshop中简单涂抹出来的 , 我们用它作为坐标系 , 让它与案例中的静止图像进行交互 , 实现了使用单帧流程图的非循环动作特效: GDC字样被吸走消失的效果 。
文章图片
在photoshop中打开贴图坐标节点标识截图 , 我们发现它就是由一个横向渐变加一个竖向渐变组成的 。 知道了这点 , 我们可以在Photoshop中制作一张简单的流程图:在红色通道中画一个横向黑白渐变 , 绿色通道中画一个竖向黑白渐变 , 蓝色通道涂黑 。 然后在这个基础上用涂抹工具来“抹”出我们想要的运动 。
把抹出来的flow-map应用到这个特效中 , 就可以将一个精灵角色吸入阿拉丁的茶壶中去!(这个案例来自我的朋友“慎独”)
文章图片
了解流程图原理后 , 特效艺术家可以快速生成流程图 。 单帧的自己绘制 , 序列帧的用FluidNinja之类的工具来制作 , 帮助我们快速创建需要的表现效果 , 并节省大量的时间 。
了解流程图工作原理的第一步是将图像的通道和纹理坐标联系起来 。 坐标X和Y是一对数字 , 而通道红和绿也是一对数字 。 如果将其对应起来 , 那么红色通道是对应于控制水平移动的X坐标 , 而绿色通道则是对应于控制垂直移动的Y坐标 。
文章图片
一张图片的大小可以这样来描述:始于左下角(x0 , y0) , 止于右上角(x1, y1).那么从0到1就是从黑到白的渐变 。 横坐标就是左右的黑白渐变 , 纵坐标就是上下的黑白渐变 。 放到一张图中就是下图这样:红色通道是左右渐变 , 绿色通道是上下渐变 , 将蓝色通道设置为纯黑色(即不使用蓝色通道) 。
文章图片
在Flow-map中 , 亮度值0是黑色、127是中间灰 , 255是白色 。 这三个亮度值 , 中间灰代表坐标原点 , 不产生运动 。 白色向一端移动 , 而黑色向另一端移动 。 我们可以将其简单总结为“X轴(红色通道)黑右白左 , Y轴(绿色通道)黑上白下”这样的基本规律 。
文章图片
了解这一点后 , 我们就可以使用Flow-map的亮度值来控制另一图像的UV坐标 , 从而掌握像素运动方向和速度 。
文章图片
在这张示例图中 , 左边是流程图 , 中间的是源图像 , 右边是不同通道生成结果 。 如果我们希望源图像只做左右移动 , 那么在流程图中我们就可以将黑白条纹设置在红色通道中 , 同时将绿色通道设置为中间灰色(127) , 这时 , Flow-map中黑色的区域会使源图像中的像素向右移动 , 白色区域向左移动;
同样的 , 如果我们希望源图像只做上下移动 , 那么在流程图中我们就可以把黑白条纹切换到绿色通道 , 红色通道设置为中间灰色(127) , 这时FlowMap中黑色区域使源图像中的像素将向上移动 , 白色区域则向下移动 。 由于是在二维的运动 , 所以我们不需要蓝色通道 , 将其设置为黑色 。
上面我们看到了不循环的像素运动效果:精灵被吸入阿拉丁神灯的动效 。 接下来讨论循环的像素动画 。
还是以GDC字母为例 。 从图中我们可以看到GDC字母在不断循环变形 。 特效师经常用这种循环像素动画来模拟河流、云等环境特效 。
为了制作循环动画 , 我们在Shader中把同一张运动图像分别进行2次处理(A部分与B部分) , 将两者的时间错开0.5秒 , 同时设置一个淡入淡出图像作为遮罩(C部分)将A、B两个部分混合到一起 , 最终的生成的GDC文字仿佛是在进行循环运动 。
制作这个循环动画的Shader的关键节点是Time和Fract , 它们产生了循环动画的运行 。 通过控制时间参数 , 我们可以准确的找到动画的断点位置 。 而C部分将帮助我们去掉动画之间的切换断点 , 实现了渐变的效果 。 正如目前我们所看到的这张数学公式图集一样 , 最初公式是以斜线(Time 节点)来表示的 , 而在末尾的公式中它变成了一条循环的波浪线(实现了渐变循环) 。 当我们将A、B、C节点连接 , 并进行差值计算(Lerp)时 , A、B两个图像进行了融合 , 并形成了无缝循环的运动动画 。
文章图片
通过这张图 , 我们可以进一步了解到数学与图像的关系 , 从算式到图形 , 再到图像 , 一些数学术语与Shader节点的意义都变得容易理解了 。 (如Fract函数实现循环 , Lerp实现图像之间差值计算等等) , 因此 , 对特效师来说 , 我们需要拥抱数学 , 因为数学是帮助我们在数字世界实现图像表现的基础 。 在特效师眼里 , 图即数字 , 数字即图 。
文章图片
到目前为止 , 我们已经了解到了单帧非循环像素动画与循环像素动画的Flow-map应用方法 。 接下来我们将看到用序列帧流程图 Shader制作的复杂像素动画 。
对于像素动画而言 , 有两个比较困难的部分:一个是图像序列生成 , 另一个则是Shader 。
文章图片
文章图片
让我们再来看一个例子 。 这张图的左侧边是一张长2秒、64帧的VFX图像 。 而右侧是一张相同VFX , 但时间长度扩大到6倍的图像 。 如果我们想通过左边的贴图资源实现右边的效果 , 就需要用到Flipbook Flow-map Shader 。 通过这个功能 , 我们可以使用尺寸很小的图像序列来实现时间很长且流畅的像素动画表现 。
例如 , 一张16帧512x512像素的图像序列纹理可以用作256帧的4096x4096像素的图像序列纹理 。 这就像原有的图像序列纹理被放大了6倍一样 。
实现这种动画的方式 , 就需要用到Flipbook Flow-map Shader 。 通过这种Shader , 我们可以生成更多的中间帧 , 从而让VFX延长数倍 。
文章图片
这是我们在ASE(Amplified Shader Editor着色编辑器)中制作了简化版的Flipbook Flow-map Shader 。 在这个版本中 , Shader的节点仅为Unreal Engine版本的1/3 。
文章图片
需要注意的是 , Unreal的贴图坐标起点(X0, Y0)在左上角 , 而Unity则是在左下角 。 所以在Unity中使用FluidNinja导出的序列帧贴图就要做一个纠正; 列值不变 , 行值要上下颠倒 。
文章图片
在这里 , Flipbook Flow-map Shader的第一部分是为当前帧和下一帧执行翻书 UV 动画功能 。 将其 UV 参数上设置的 UV 坐标转换和动画化 , 按顺序访问由列参数和行参数指定大小的网格上的单元格 , 从开始帧中指定的单元格开始 , 并以一定速度变化 。 而第二部分 , Flipbook Flow-map Shader则是相应的扭曲密度图的UV坐标 , 并将当前帧和下一帧混合 。
文章图片
我的同事图形程序张传迪将Flipbook FlowMap Shader优化成了几行代码 。
文章图片
这张图展示了Flipbook Flow-map Shader的工作原理:将当前帧将向外放大 , 将下一帧向内缩小 , 同时控制好融合时间与中间帧 , 最终 , 我们将通过Flipbook Flow-map Shader实现在不增加贴图大小的情况下 , 实现时间更长且动作丝滑的动画表现 。
对于像素动画的控制 , 除了上述提到的Flow-map的3种类型 , 我们也可以直接利用材质节点来控制图形的变化 。
第一个例子是通过数学实现音乐的视觉表达 。 从前面的介绍中可以得知 , 我们能通过一张图片来控制另一张图片的坐标 , 那么如果我们用它来控制几何网格的世界坐标位置呢?
我们来看这首《Who Let The Dogs Out》的VFX表现 。 在这里 , 我把FUN这3个英文字母分割成几十个方块 , 再把音乐节奏转换为灰度图在各通道记录下来 , 并用它来控制方块的高度 , 实现了文字随音乐跳动的效果 。 通过这个案例 , 我想说的是图形是数字的一种形式 , 音乐也是数字的一种形式 , 我们使用不同类型的数字 , 数列去制作特效 。 把数学变成视觉表达就像“放狗出来”这音乐本身一样特别有趣 。
文章图片
这里以通过燥点图控制一个圆球的世界坐标高度变化做了一个简单的案例 。 我们通过数学的方法 , 制作一个如下图公式所述的曲线 , 结合噪波图的运动控制球体顶点动画 , 包括高度 , 速度以及色彩 。
文章图片
特效师总是用各种方式来改变图形或多面体的2D或3D坐标来操纵像素及顶点动画来实现特效 。
文章图片
我们可以用Dot、Sin、Cosine、Panner 等着色器节点以程序方式生成像素动画 。 比如像GDC火焰下面的水波纹效果 。
文章图片
文章图片
文章图片
在这个水波FX中 , 我们只使用了一个很小的法线贴图 , 其余如GDC 字母上的图案、圆形遮罩、线条、波纹及其运动都是通过数学节点直接生成的 。 数学是特效师的好朋友 , 我觉得做特效很多时候是数学搭台 , 艺术唱戏 。
我们来看看这个波纹效果制作的背后的公式以及原理:我们通过g[f(uv)] = sin(f(uv)) = sin((u-0.5)^2 + (0.5-0.5)^2) f(uv)这则公式得到一个以纹理中心为原点的圆 。 假设y=0.5 , 那么f(uv) = (u-0.5)^2 + (0.5-0.5)^2 = (u-0.5)^2 。
文章图片
从图表中可以看到 , 圆的半径从中心向外延展 , 并越来越紧凑 。 这是由于我们使用周期函数 sin(x) 将圆从中心向外展开 , 而最终 , 我们通过g[f(uv)] 产生一组圆 , 并从中心越来越快的散开 。
文章图片
文章图片
像素动画广泛应用在趣加互娱的各个项目 。 趣加互娱制作的Puzzle类型游戏《Call of Antia(安提亚的召唤)》 , 我们可以看到图片中的水、飞龙四周的云彩以及角色的头发等都可以用像素动画实现 。 不止特效 , 像素动画也可以应用到角色 , 场景 , 和UI设计中 。
下面让我们进行一下总结:
文章图片
作为手游特效师 , 我们需要快速制作出适用于移动设备性能的高品质视觉表现 。
1. FluidNinja是一款绝佳的像素动画制作工具 , 它可以通过粒子系统、位图、矢量场等输入方式来即时模拟各种流体动画 , 并快速生成Flipbook Flow-map纹理 。
2. 在Flow-map中 , 我们通过红色通道、绿色通道的亮度值来控制另一幅图片的坐标 。 (这里我们也总结一个简单的记法:【红色通道】黑右白左 , 【绿色通道】黑上白下) 。
3. 像素动画的原理:Flow-map的中间灰色不运动 , 黑色向一个方向移动 , 白色向相反方向移动 。
4. 通过Flipbook Flow-map Shader , 我们能使用小尺寸的序列帧贴图 , 为手戏生成高时长并且动作平滑的像素动画 。
希望以上这些像素动画技术的分析以及应用数学来表达视觉的方式对你的工作有所帮助 , 谢谢大家!
推荐阅读
游戏公司招聘季 | 社畜的福报| 2022工业化之战
天美技术策划 | 盲人MMO | 国产模拟经营出海
文明与征服|游戏王 | 山东酒桌桌游
【动画|趣加互娱首席特效专家张韶勇GDC2022演讲:数学在特效制作中的重要性】点击下方公众号名片 , 获取游戏行业更多信息
推荐阅读
- 凌波丽|卫龙辣条被指打色情擦边球 新网球王子动画7月播出|每日B报
- |光遇手游参加动漫日本(animejapan)大型动画展览会
- 幽灵线|《王者荣耀》推出新动画,播放量不佳,游戏改编的动画为何难火?
- 游戏|育碧展示AI工具ZooBuilder 帮助制作动物动画骨骼
- |动画人和游戏人的区别在哪里?
- |索尼互娱宣布收购haven工作室
- 索尼互娱|索尼互娱确认收购Haven Studios 为PS5开发游戏
- 动画|影视、游戏行业相爱相杀,人才最终要去何处?
- 小智|宝可梦劲敌宿命之战,动画当中小智对战真司,哪个水平最高?
- 动画|光遇:献祭过程优化,掉翼动画被取消,老玩家和萌新都笑了