uid vfx_使用视觉效果图升级FPS样本中的VFX

uid vfx

Last year, at Unite LA, we unveiled our FPS Sample project and Visual Effect Graph. FPS Sample is aimed to show developers how to set up a first-person shooter. The first release came with effects made using Particle System, the current production-ready solution for particles. Afterward, we upgraded all the visual effects to use the brand new Visual Effect Graph, in order to take advantage of HDRP. Since Visual Effect Graph is still in preview, this was a valuable chance to gather information and try out production patterns so we can improve the tool towards a production-ready state. Here’s a post-mortem of the upgrade process and some of the lessons we learned.

去年,在Unite LA,我们推出了 FPS示例 项目和 视觉效果图 。 FPS Sample旨在向开发人员展示如何设置第一人称射击游戏。 第一个版本带有使用“粒子系统”(当前可用于生产的粒子解决方案)制作的效果。 之后,我们将所有视觉效果升级为使用全新的视觉效果图,以利用HDRP。 由于Visual Effect Graph仍处于预览状态,因此这是收集信息和试用生产模式的宝贵机会,因此我们可以将工具改进为生产就绪状态。 这是升级过程和我们学到的一些经验的总结。

从一个系统到另一个系统的轻松转换 (A pretty easy transition from one system to another)

Visual Effect Graph is a package that comes with a simple Component that runs effects from templates, which is pretty different from the Particle System solution, that embeds all effect data in a scene component. Also, Visual Effect Graph enables you to embed multiple components into a single effect graph, so that Unity uses only one component to render multiple particle systems.

视觉效果图是一个带有一个简单组件的软件包,该组件从模板运行效果,这与“粒子系统”解决方案完全不同,后者将所有效果数据嵌入场景组件中。 另外,视觉效果图使您可以将多个组件嵌入到单个效果图中,以便Unity仅使用一个组件来渲染多个粒子系统。

However, we made the C# interface pretty close to the one Particle System uses, so the behaviors are really similar and it’s quite easy to upgrade from one system to another.

但是,我们使C#接口非常接近一个粒子系统使用的接口,因此行为确实相似,并且从一个系统升级到另一个系统非常容易。

For FPS Sample, the transition to the new system was pretty easy due to the following:

对于FPS Sample,由于以下原因,过渡到新系统非常容易:

  • Few references to particle systems in C# Code

    在C#代码中很少引用粒子系统

  • (Almost) Same C# Component API

    (几乎)相同的C#组件API

  • Game code structure easy enough to make additional optimizations.

    游戏代码结构足够简单,可以进行其他优化。

We started the transition by finding all references to Particle Systems in prefabs and code, then we replaced all the instances with placeholders, in a really naive manner. A pretty easy task as all gameplay effects were stored in dedicated project folders under the Assets/Effects hierarchy.

我们通过在预制件和代码中找到对粒子系统的所有引用来开始过渡,然后以一种非常幼稚的方式将所有实例替换为占位符。 一项非常简单的任务,因为所有游戏性效果都存储在Assets / Effects层次结构下的专用项目文件夹中。

All other effects in the scene were easily identified using the hierarchy filters. Most of these were stored in prefabs so the replacement with placeholders was an easy task too.

使用层次过滤器可以轻松识别场景中的所有其他效果。 其中大多数存储在预制件中,因此用占位符替换也是一件容易的事。

Once replaced, there was some latitude left to improve and iterate on effects.

更换后,还有一些余地可以改善和迭代效果。

使用VFX Graph优化拍摄系统 (Optimizing a shooting system with VFX Graph)

Shooting systems rely on many effects whose performance depends on the pace of the game, the number of players, the playing area topology, and the current game’s state. This implies that many objects can be spawned around (for instance: impacts) and will fill the scene graph with many draw calls.

射击系统依赖于许多效果,这些效果取决于游戏的节奏,玩家数量,游戏区域拓扑以及当前游戏的状态。 这意味着可以在周围生成许多对象(例如,碰撞),并且将使用许多绘制调用来填充场景图。

The FPS implementation was made using a pool of 64 impacts, managed by Entity-Component Systems using a recycling system: 1 Particle System per impact + 1 Audio Source.

FPS实施使用64个影响池进行,并由实体组件系统使用回收系统管理:每个影响1个粒子系统+ 1个音频源。

The main drawback of this system was that every instance of an impact would lead to a draw call per-system. A constraint that requires using only a few draw calls per effect would, in a worst-case scenario, lead to N times 64 draw calls (N being the number of particle systems that compose each impact), for each kind of impact.

该系统的主要缺点是,每个碰撞实例都会导致每个系统进行一次抽签。 在最坏的情况下,每个效果只需要使用几个绘制调用的约束将导致N次乘以64次绘制调用(N是构成每种效果的粒子系统的数量)。

共享池系统的实现 (Implementation of a shared pool system)

An improvement that came pretty quickly was to use a common simulation for all kinds of impacts of a single weapon type. This way, all the rendering would be performed in the same simulation. We assumed the drawback of sorting all impact systems together instead of sorting each impact individually, as it would let us:

很快出现的改进是对单个武器类型的所有撞击使用通用的模拟。 这样,所有渲染将在同一模拟中执行。 我们假设了将所有影响系统分类在一起而不是分别对每个影响进行分类的缺点,因为它会让我们:

  • Render many more particles per system, which is more efficient for a GPU Simulation

    每个系统渲染更多的粒子,对于GPU仿真更有效

  • Use more systems (layers) of particles to make richer effects.

    使用更多的粒子系统(层)以产生更丰富的效果。

  • Still perform distance-to-camera computations so we could do some kind of LODs

    仍然执行到相机的距离计算,因此我们可以执行某种LOD

In order to do that, we used the VFX SendEvent() API and VFXEventAttribute payload in order to place the impact source and the impact normal.

为此,我们使用了VFX SendEvent()API和VFXEventAttribute有效负载,以放置冲击源和冲击法线。

The impact definition would only reference an asset template and a scene-level manager would be in charge of handling master simulation objects and sending events: Entering VFXSystems.

影响定义将只引用资源模板和场景级经理将负责处理主模拟对象,并发送事件:进入 VFXSystem

VFXSystem is a top level class we developed for FPS Sample that’s in charge of handling all pooled effects. The behavior is the following:

VFXSystem是我们为FPS Sample开发的顶级类,负责处理所有合并的效果。 该行为如下:

  • A player triggers a pooled effect that needs to be handled by VFXSystem

    玩家触发需要由VFXSystem处理的合并效果

  • VFXSystem gets the attributes of this effect (position / normal in the case of an impact)

    VFXSystem获取此效果的属性(发生碰撞时的位置/法线)

  • VFXSystem also gets the template of this effect.

    VFXSystem也获得此效果的模板。

  • If the template is not already spawned, we spawn it.

    如果尚未生成模板,则我们生成它。

  • Either way, we send an event to this system, with an attribute payload that corresponds for instance to the impact position and normal.

    无论哪种方式,我们都会向事件系统发送一个事件,该事件的属性有效负载例如对应于撞击位置和法线。

  • At level change, we reset the pooled effects.

    在级别更改时,我们重置合并的效果。

This custom pooled system, while being a major improvement in terms of performance, also came with its drawbacks:

这种自定义池化系统虽然在性能方面进行了重大改进,但也具有以下缺点:

  • Effects designed with event attributes need to be triggered using C# API (because of attributes) which isn’t ideal to preview and author (see VFX Event Tester for our solution).

    使用事件属性设计的效果需要使用C#API触发(由于属性),这对于预览和创作不是理想的选择(有关解决方案,请参见VFX事件测试器)。

  • Effects need to be customized using a large bounding box. In FPS Sample we set it statically so it encompasses the whole level. As a takeaway, we could also have managed this bounding box in C# so it grows and shrinks with virtual living impacts.

    需要使用大型边框自定义效果。 在FPS示例中,我们将其静态设置为涵盖整个级别。 作为外卖,我们也可以在C#中管理此边界框,使其随着虚拟生活的影响而增长和缩小。

  • Effect LODs are computed at spawn time so far away impacts are being simplified at all times (this was indeed a deliberate choice for performance).

    效果LOD是在生成时计算的,因此始终会简化远距离的影响(这确实是性能的故意选择)。

VFX事件测试仪 (VFX Event Tester)

VFX Event Tester was a feature that came pretty early while working with pooled effects. As these effects need to be started using event attributes (impact position and normal, bullet hit scans source and target positions), some C# is needed to store these attributes.

VFX Event Tester是一项功能,在处理合并效果时很早就出现了。 由于需要使用事件属性(碰撞位置和正常位置,子弹命中扫描源位置和目标位置)来启动这些效果,因此需要一些C#来存储这些属性。

The solution that came first was to use a dummy timeline with VFX Activation Tracks that sent parametrized effects in order to preview the effect. The drawback was a prefab that was needed to be embedded in the scene for editing, and removed afterward, which was not ideal.

首先出现的解决方案是使用带有VFX激活轨道的虚拟时间线,该虚拟时间线发送了参数化效果,以便预览效果。 缺点是需要将预制件嵌入场景中进行编辑,然后再将其删除,这是不理想的。

Instead of that, we developed a SceneView utility window named VFX Event Tester. This window enables sending events with attribute payloads to currently selected asset.

取而代之的是,我们开发了一个名为VFX Event Tester的SceneView实用程序窗口。 该窗口允许将带有属性有效负载的事件发送到当前选定的资产。

The tool can be toggled on and off via the Edit > Visual Effects > Event Tester menu when needed. The source code can be accessed at the following location: Assets/VFX/VisualEffectGraph-Extras/Editor/Utility/VFXEventTester/VFXEventTesterWindow.cs

需要时,可以通过“ 编辑”>“视觉效果”>“事件测试器” 菜单 打开和关闭该工具 。 可以在以下位置访问源代码: Assets / VFX / VisualEffectGraph-Extras / Editor / Utility / VFXEventTester / VFXEventTesterWindow.cs

自定义粒子LOD系统 (Custom Particle LOD system)

For all impacts, spawning all of the effects components at all times would be far beyond necessary, especially for really small particles. In order to solve depth-dependent rendering, we implemented a rudimentary yet useful filtering system for particles: Cancel By Distance. The system is a kind of gate that will null the spawn of particles if some conditions are valid.

对于所有冲击而言,始终生成所有效果组件都远远超出了必要,特别是对于很小的粒子。 为了解决与深度有关的渲染,我们为粒子实现了一个基本但有用的过滤系统: 按距离取消 。 该系统是一种门,如果某些条件有效,它将使粒子的产生无效。

Using this simple LOD system helped avoid unnecessarily spawning barely visible particles for the impacts. However, it also required to stop spawning far away effects such as rocks in the grinding drill machine effect.

使用此简单的LOD系统有助于避免不必要地生成几乎看不见的粒子来产生影响。 但是,还需要在磨钻机效果中停止产生较远的效果,例如岩石。

You can find the source code of this custom Spawn block at: Assets/VFX/Script/CustomSpawners/CancelByDistance.cs

您可以在以下位置找到此自定义Spawn块的源代码: Assets / VFX / Script / CustomSpawners / CancelByDistance.cs

VFX音量混合器,在播放器周围混合效果 (VFX Volume Mixer, blend effects around the player)

Deploying effects in a short time frame can be problematic so we chose to use a single effect around player’s camera and use the SRP Volume system to blend effects around the player depending on its position.

在短时间内部署效果可能会出现问题,因此我们选择在播放器的摄像机周围使用单个效果,并使用SRP音量系统根据播放器的位置混合效果。

The volume mixer takes advantage of the SRP Core feature named Volume. These classes enable the use of parameters stored in the volume system, such as rendering parameters and post-processes, enabling overrides of the settings depending on the camera position in the level.

音量混合器利用名为Volume的SRP核心功能。 这些类允许使用存储在体积系统中的参数(例如渲染参数和后处理),从而可以根据级别中的摄像机位置来覆盖设置。

You can access the source code of this system at the following location: Assets/VFX/Script/VFXVolumeMixer

您可以在以下位置访问此系统的源代码:Assets / VFX / Script / VFXVolumeMixer

This system was used in order to deploy an environment effect that matches the player’s camera. This creates heat effects on the exterior and the furnace room, dust for the interiors and the cave.

使用此系统是为了部署与玩家的相机匹配的环境效果。 这会对外部和炉室产生热效应,对内部和洞穴产生灰尘。

In order to use this system, there’s a set of values that you need to set up in the project settings.  The system is able to control up to 8 floats, 8 vectors, and 8 color values. The settings will let you choose how many of these you want to use and give a name to these variables.

为了使用该系统,需要在项目设置中设置一组值。 该系统最多可以控制8个浮点,8个向量和8个颜色值。 通过设置,您可以选择要使用的数量,并为这些变量命名。

Then you can add a VFX Volume Mixer volume component to n your scene volumes that will prompt you these values so you can make local overrides in your level. It’s a pretty convenient way to be able to make local overrides. 

然后,您可以在场景体积中添加VFX Volume Mixer体积分量,以提示您这些值,以便您可以在关卡中进行本地替代。 这是能够进行本地替代的一种非常方便的方法。

Finally, if you want to sample a value from these volumes, you can use the VFX Volume Mixer Parameter binders.

最后,如果要从这些音量中采样值,则可以使用VFX音量混合器参数绑定器。

Level_01中的其他英雄特效 (Other Hero Effects in Level_01)

FPS Sample also displays some particle systems we used in the Level_01 scene and that aren’t part of a generic system. Here are some cases we solved:

FPS示例还显示了一些我们在Level_01场景中使用的粒子系统,这些粒子系统不是通用系统的一部分。 这是我们解决的一些情况:

捕获点圈 (Capture Point Circle)

The capture point circle is a pretty interesting effect because it requires particles to follow a deformable path made out of a skinned tube with 16 control points. As the Visual Effect Graph isn’t able to handle spawn on skinned meshes at the moment, we still have information about this bone chain. Also, for smooth 3D interpolation for this effect, the Sample Bezier operator is something that came very valuable.

捕获点圆是一个非常有趣的效果,因为它要求粒子遵循由带有16个控制点的蒙皮管制成的可变形路径。 由于视觉效果图目前无法处理蒙皮网格物体上的生成,因此我们仍然可以获得有关此骨骼链的信息。 同样,对于这种效果的平滑3D插值,Sample Bezier运算符非常有价值。

In order to spawn particles on a path composed of multiple positions, a pretty straightforward method is to bake the position list into a position attribute map, then sample this texture’s pixels in order to determine where the particles need to be spawned.

为了在由多个位置组成的路径上生成粒子,一种非常简单的方法是将位置列表烘焙到位置属性图中,然后对该纹理的像素进行采样,以确定需要在哪里生成粒子。

For this specific case, we wrote a new parameter binder named Multiple Position binder, that takes a list of game objects, and will write into a texture every game object world-space position, then set the point count and the texture to parameters exposed in the specific visual effect graph.

对于这种特定情况,我们编写了一个名为“多重位置绑定器”的新参数绑定器,它接收游戏对象列表,并将每个游戏对象的世界空间位置写入纹理,然后将点数和纹理设置为在具体的视觉效果图。

Sampling this position map is then pretty easy. We consider a group of 2 pixels as 4 bezier points (by computing 2 intermediate bezier tangents), then we interpolate everything so all the particles will go through all positions with bezier blending.

然后对该位置图进行采样非常简单。 我们将一组2个像素视为4个bezier点(通过计算2个中间bezier切线),然后对所有内容进行插值,以便所有粒子将通过bezier混合穿过所有位置。

You can find this example in the prefab located at: Assets/Prefabs/Gameplay/Capturepoint_A, the effect is located in the Small_emitter Game Object.

您可以在位于以下位置的预制件中找到此示例: Assets / Prefabs / Gameplay / Capturepoint_A 效果位于 Small_emitter 游戏对象中。

The source code for the Multiple position binder is available in the project at this location: Assets/VFX/Script/ParameterBinders/VFXMultiplePositionParameterBinder.cs

项目中的以下位置提供了多位置装订器的源代码: Assets / VFX / Script / ParameterBinders / VFXMultiplePositionParameterBinder.cs

磨石机 (Rock Grinder)

Rock grinder is a simple decorative effect used at the canyon’s end. It’s used to emphasize the power of a Grinding Drill. The Drill is stuck and is grinding the rock formation on its left as well the Terraformer’s egg that serves as a capture point.

岩石研磨机是在峡谷末端使用的一种简单装饰效果。 它用来强调“研磨钻头”的功能。 钻头被卡住,正在研磨左侧的岩层以及用作捕获点的Terraformer的卵。

灰尘和管道蒸汽 (Dust and duct steams)

Across the level, there are many light sources that needed to be decorated using simple steam, dust, and air flow effects. While most of these are static sources, some are animated, for instance, this rotating air duct.

在整个关卡中,需要使用简单的蒸汽,灰尘和空气流效果来装饰许多光源。 尽管其中大多数是静态源,但有些是动画,例如,旋转的风管。


In order to solve this case, we used specifically lit particles in order to synchronize the steam reveal and the volumetric light shaft. In order to keep a decent frame rate, these particles needed to be faded out pretty far from the camera because their shader was per-pixel lit and it was too resource-intensive to be rendered full screen.


为了解决这种情况,我们使用了专门点燃的颗粒,以使蒸汽泄漏和光轴体积同步。 为了保持适当的帧速率,这些粒子需要从相机远处淡出,因为它们的着色器是按像素点亮的,而且资源过于密集而无法全屏显示。


Other effects were placed through the level, this time set up as unlit particles in order to save performance. The big vertical air ducts could have been lit as well but their size was a bit too problematic performance-wise. Plus, the light shaft wasn’t sharp enough so we did end with simple unlit effects. All these instances were configured directly in the scene by setting up fading distances and color.


其他效果通过关卡放置,这次设置为未照明的粒子以节省性能。 大型垂直风管也可以点亮,但是它们的尺寸在性能上有点问题。 另外,光轴不够锐利,因此我们以简单的不发光效果结束。 所有这些实例都是通过设置衰落距离和颜色直接在场景中配置的。

炉效 (Furnace Effect)

The furnace effect is a pretty simple effect that spawns bubbles on a circle shape and uses the experimental GPU Events in order to spawn bubble burst flipbooks and upping sparkles upon each bubble collapse.

熔炉效果是一种非常简单的效果,它以圆形形状生成气泡,并使用实验性的GPU事件来生成气泡破裂的活页簿,并在每次气泡崩溃时增加火花。

Also, it is generally decorated using non-localized upping sparkles, steam and heat effects.

同样,它通常使用非本地化的火花,蒸汽和热效应进行装饰。

While it is possible to get really close to this effect, we used a Camera Fade block for steam and heat so it soothes the overdraw and keeps the framerate under control.

虽然有可能真的接近这种效果,但我们使用Camera Fade块处理蒸汽和热量,因此它可以缓解透支并保持帧速率在可控范围内。

结论 (Conclusion)

The transition to Visual Effect Graph in FPS Sample was smoother than expected, as the package is still in preview, the system still allows some flexibility in order to customize the experience for the project’s needs. Luckily, FPS Sample project structure is super clean, uses really few workarounds and/or custom implementations, so it was a really good test candidate for a Visual Effect Graph Implementation. Still, we’re aware that it could have been a totally different and harder story in a wilder project. In any case, it enabled us to pinpoint production cases we will address for the next versions of Visual Effect Graph in 2019.

在FPS示例中,过渡到视觉效果图的过程比预期的要平滑,因为该软件包仍处于预览状态,因此该系统仍具有一定的灵活性,以便根据项目的需要自定义体验。 幸运的是,FPS Sample项目结构非常干净,几乎没有使用任何变通方法和/或自定义实现,因此它是Visual Effect Graph Implementation的非常好的测试候选人。 不过,我们知道,在一个较野蛮的项目中,这可能是一个完全不同且困难的故事。 无论如何,它使我们能够查明生产案例,我们将在2019年解决下一版本的Visual Effect Graph。

Some features were developed here specifically for the needs of the integration; we will still keep these as a reference in order to come up with more generic tools in the future.

这里专门针对集成需求开发了一些功能; 我们仍将这些作为参考,以便将来提供更多通用工具。

翻译自: https://blogs.unity3d.com/2019/04/10/upgrading-vfx-in-the-fps-sample-with-visual-effect-graph/

uid vfx

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值