UDN
Search public documentation:

MotionBlurSkinningCH
English Translation
日本語訳
한국어

Interested in the Unreal Engine?
Visit the Unreal Technology site.

Looking for jobs and company info?
Check out the Epic games site.

Questions about support via UDN?
Contact the UDN Staff

UE3主页 > 后期处理特效 > 运动模糊植皮后期处理特效功能
UE3 主页 > 过场动画制作人员 >运动模糊植皮后期处理特效功能

运动模糊植皮后期处理特效功能


3small.png
向不同方向移动的身体部分显示不同的运动模糊方向和强度。

概述


推荐阅读: 运动模糊

在实现 运动模糊植皮 之前,我们仅支持基于相机和对象运动(平移、旋转、缩放)的 刚体运动模糊 。植皮网格物体继承了对象根骨骼的对象运动,该运动可以很好地进行简单对象的运动效果,但对于不适用于角色。躯体的不同部分向不同的方向运动,这需要更加成熟的处理方法。

PerBoneMotionBlur.jpg
左侧: 启动该功能
中间: 禁用该功能
右侧: 显示为颜色的每个像素速度。

植皮运动模糊需要一些额外的CPU和GPU性能,并且会产生额外的内存消耗。由于这个原因,所以该功能应该仅在需要的地方使用。对于所有其他对象来说, 刚体植皮运动模糊 仍然可用。

激活该功能


如果平台(请参阅后面的关于这个主题的部分)支持这个功能,可以通过设置ini文件"BaseEngine.ini"中的"MotionBlurSkinning"或者稍后在运行时通过控制台命令 "MotionBlurSkinning"来激活这个功能。

在ini设置中指定的数值和控制台命令所使用的数值是一样的。它不仅允许您切换功能的打开(1)和关闭(0)状态,同时它会覆盖面每个对象的标志,强制使它应用于所有的对象(2)。当使用控制台命令没有额外的参数时可以看到当前状态及一些帮助:

ConsoleMotionBlurSkinning.jpg
当使用 MotionBlurSkinning命令时的反应。

设置骨架网格物体标志


这个标志是 bPerBoneMotionBlur ,可以通过代码(比如!UnrealScript)或者当在关卡中放置对象时进行设置。

editorflag.jpg

实现


植皮运动模糊正在把每个像素运动向量输出到速度贴图中(目前相机运动是黑色、对象运动是彩色,更多细节请参照: 运动模糊)。在渲染完所有的速度后,以下的步骤和 刚体运动模糊植皮运动模糊 没有差别。

我们把在这帧中使用的所有对象的骨骼数据存储到贴图中,以便在下一帧中使用。这意味着我们总是需要两个贴图,因为我们在同一帧中从一个贴图(GPU)中读取数据然后写入到另一个贴图(CPU)中。这最小化了贴图锁定次数。修改引擎使用三重缓冲,某些人或许必须向这个链中添加另一个缓冲器。

使用顶点着色器常量可以实现这个功能,但是因为这些常量是有限的,我们面临着把数据放入到着色器中的挑战。GPU植皮已经几乎使用了所有的常量,而对于植皮运动模糊我们需要双倍的常量数量(我们既需要当前的骨骼矩阵也需要前一个骨骼矩阵)。打包数据或许是一个选择(比如四个一分组+缩放+位置),但是没有进一步的更复杂的处理。把描画函数分割为骨骼数量一半的块数是另一种解决这个问题的方法,但是这会降低其他渲染遍数的渲染器性能,并且会给内容准备(烘焙/导入)添加更大的复杂性。

我们决定使用"顶点贴图获取"来实现植皮运动模糊。这个GPU功能并不是在所有硬件上都支持,尤其是早期的 ShaderModel 3.0硬件 (AMD/ATI)不支持该功能。

我们使用CPU中的骨骼数据来更新贴图。为了获得更好的贴图缓存性能,我们使用一维贴图。

我们把网格物体分割成块来遵守骨骼数量的限制(有限的顶点着色器常量),并通过材质来分割网格物体。

骨骼看上去可能是一样的,因为我们使用了每个块索引,而那些索引对应到了一个骨骼子集上。

骨骼数量限制

因为我们使用1维的贴图来存放骨骼数据,所以在骨骼数量上有一些限制。我们目前使用宽4096的贴图,每个骨骼需要存储3个贴图像素。请使用 stat SceneUpdate 命令来查看这个限制是否影响您。我们仅对附近的对象进行运动模糊处理,对于我们使用的骨骼数量来说,我们并没有把这个当成问题来看待。注意,脸部动画的运动模糊通常不需要!MotionBlurSkinning功能。

着色器变换

无论是具有植皮运动模糊还是没有运动模糊植皮功能,我们都尝试避免着色器变换。这会保持代码复杂度较低并且一般会具有较少的着色器。我们决定使用静态分支(和一个布尔着色器常量比较),因为这解决了问题并且经过了驱动程序优化。

在 Xbox360上,我们使用静态分支来避免着色器变换。我们验证确定这和编译出来的一样快。但其他的平台还没使用这个方法(请参照优化部分)。

性能


CPU数据更新

植皮运动模糊的CPU消耗不像从先前帧中存储的用于后续帧的数据的性能消耗那样高。因为我们仅是增减双倍的缓存,所以贴图锁定操作是应该不会延迟,但是请确保我们在这上面有一个 stat(统计数据) 。通过使用控制台命令 stat SceneUpdate ,您可以参看这个数值。

StatSceneUpdate.jpg
统计数据显示了锁定的CPU事件及已经更新的骨骼数量。

更多的描画函数

运动模糊的对象需要在速度渲染那遍进行渲染(以便存储每个像素的运动模糊向量)。如果非植皮运动模糊,我们仅在有对象运动时需要进行这个处理。为了测试植皮对象是否运动,我们需要检测更多的数据。我们还有对此进行优化。这个处理可以完成,但是对于具有很多运动对象的最糟糕的情况,这没有什么作用。

那意味着当为一个没有运动的对象启用运动模糊时(比如,不移动的机器人),现在就要渲染它并且需要添加更多的描画函数。

顶点贴图获取的GPU消耗

当前的方法需要把12个顶点贴图取入到一个非常大的顶点格式中(一个4x3的骨骼矩阵需要4个浮点数,需要对4个骨骼进行植皮)。这意味着需要渲染更多的顶点,渲染速度会更慢。使用这种方法仅渲染附近的对象(速度渲染那遍),所以渲染器的性能消耗会由于大量的邻近动作而加剧。

当在Xbox360(具有变形顶点的浓密的三角形网格物体)上优化速度渲染时, 我们注意到渲染速度比刚体运动模糊慢60%(所有的对象都移动了,从而不能进行跳跃渲染)。

内存


这个功能的内存消耗是个常量,因为存放数据的两个贴图的大小是固定的。这避免了重新分配的性能消耗和内存碎片。为了看到占用了多少内存,我们跟踪这个内存。您可以使用 stat memory 控制台命令来查看数据:

StatMemory.jpg

不同平台上的支持


我们的实现是基于 顶点贴图获取 功能的,不是所有GPU都具有该功能。目前,我们在!Direct3D 9 (如果硬件支持它)和Xbox360上支持植皮运动模糊。在Playstation 3平台上添加这个功能是非常简单的,但是性能速度太慢(如果实现贴图获取和较高的顶点数量)。以后将会支持未来的!DirectX版本。目前还没有打算提供移动硬件的支持(性能原因)。

如果平台不能支持该功能,那么引擎就会自动地使用 刚体植皮运动模糊 作为替换。

优化:


  • 在Xbox360上,可以使用"vfetch"功能而不是使用顶点贴图获取功能。
  • 我可以在每个顶点上进行小于4次的骨骼查找(降低了质量但是是可以接受的)。
  • 我们可以在运行时检查bPerBoneMotionBlur,以便当它知道对象没有运动时可以禁用游戏代码(很简单但是需要处理游戏代码)。
  • 在PC和Playstation 3上使用静态分支。由于有个引擎bug所以我们还不能使用它。作为一个解决方案,我们可以判断浮点数的状态来禁用那个功能(这意味着非植皮对象在速度渲染时着色器性能消耗代价很大)。
  • 目前即时仅使用了部分贴图,我们也会锁定整个贴图。
  • 通过把所有的骨骼和之前的骨骼比较来测试是否需要速度渲染。

有用的控制台命令


MotionBlurSkinning
如上所描述的。