Visual Effect Graph受到主流电影特效软件的启发,加入了许多相同的强大功能用于创作实时视觉效果,下面视频将对Visual Effect Graph进行简要介绍。 入门 请点击Unity编辑器菜单Window > Package Manager,点开Advanced并选中“Show preview packages”,然后找到Visual Effect Graph,单击Install按钮即可。 目前,Visual Effect Graph运行于Unity 2018.3的高清晰渲染管线,对轻量级渲染管线的支持预计在之后的版本推出。为了使用Visual Effect Graph,请确保你的Unity项目使用High-Definition RP模板。 为了创建视觉效果,请在项目窗口点击右键,依次选择Create > Visual Effects > Visual Effects Graph。 创建资源后,将其拖到场景视图或层级窗口。 Visual Effect Graph窗口 Context包含多个属性模块,用于表示应用于粒子的操作顺序。节点之间互相连接,会执行一系列输入属性模块的计算,从而定义粒子属性。节点系统会让使用Shader Graph着色器视图的用户感到很熟悉,但二个工具并不完全相同。 创建Context或单个节点,可以点击空格键,或单击右键,选择Create Node。创建属性模块,可在节点中点击空格键,或者单击右键,选择Create Block。 1、Context System是Initialize、Update和Output的Context组合。它由虚线轮廓表示。多个系统可以存在同一个Visual Effect Graph资源中。 Spawn定义生成粒子的数量和时间,例如Periodic Burst(间歇性喷发)、Constant(持续喷发)和Single Burst(单次喷发)等。 Initialize的前二个属性为Capacity(同时存在粒子数量)和Bounds(区域)。 Capacity确定每次系统中可以存在的粒子数量。 请注意:Capacity属性会根据粒子数量分配合适的内存,所以该数值应该对应可生成的粒子数量进行设置。通常,该值的计算公式为:Rate × Max Lifetime = Capacity Bounds定义摄像机视图中粒子生成和模拟的区域。 Update会不断改变粒子属性,它是唯一可以使用作用力的部分。 Output会渲染粒子,它决定生成的粒子类型、纹理、颜色和方向。我们可以在此对粒子的大小,位置等属性进行最后调整。每个粒子系统可以有不同的输出结果,每个输出结果可以调整多数粒子属性。 2、Block 我们可以通过取消勾选名称右侧的复选框禁用属性模块。有些输入内容可以通过点击输入名称左侧的小箭头展开,可以访问并修改详细属性,例如:Vector3的X,Y和Z。 在视图中选择Block和Context时,我们可以通过检视窗口修改它们。因此在创作视觉效果时,显示检视窗口可以方便创作过程。 3、Node 流程工具 但是对于比较复杂的系统,编译时间可能较长。禁用Auto Compile后,视图只会在保存或单击Compile按钮时进行编译,这样在大幅改动视图时,不必在每次调整后等待较长时间。 2、Blackboard 创建新参数,请点击Blackboard右上角的+图标。 3、Target GameObject 附加游戏对象,请点击场景中已打开的视觉效果实例,然后点击Attach,直接从场景实例打开视觉效果也会自动将该面板附加到游戏对象上。 4、Parameter Binders 添加Parameter Binder组件,请在层级窗口选中视觉效果,单击Add Component,搜索“Binder”并添加。将游戏对象拖到标着“None”的方框,然后点击 ⌄ 图标选择合适的参数。 与现有粒子系统比较 从上面的对比图中,我们可以看出Visual Effect Graph的优点是能够模拟数百万个粒子,计算复杂的模拟过程,以及读取帧缓冲区。而粒子系统可以使用基础物理系统,并通过回读来与游戏交互。 特别需要注意的是设备兼容性,部分设备不支持Visual Effect Graph所需的计算着色器,例如:大多数的手机。 支持的数据类型 Point Cache保存空间中点的属性,例如:Transform、法线、颜色和UV。 下面的示例是在其它工具制作骷髅,然后导入Unity来创建魔法效果。 VFX Toolbox工具集 下载VFX Toolbox工具集: 1、Image Sequencer 2、Point Cache Bake Tool 使用技巧 Context Names环境名称可以让你命名Context环境,只需双击Context环境标题部分的小型区域即可。 创建System Name系统名称,请双击虚线轮廓顶部下的小型区域。 Sticky Note便签功能可以创建可调整大小的文本框。创建标签,请在视图的空白区域单击右键,选择Create Sticky Note。 便签中,字体大小从Small到Huge共有四个选项,右键单击便签并从列表中选择修改字体大小。调整便签大小,可以拖动便签边缘或边角进行调整。 Node Group节点分组为节点的分组设置标题,并将它们作为整体进行移动。创建节点分组,请选择一组节点后,右键单击一个选中节点,然后选择Group Selection。 如果要移动节点到节点分组,将该节点拖入已有分组即可。如果要将节点移出分组,按住Shift键然后将其拖出分组。如果要删除分组而不删除节点,单击选中分组标题,然后按下Delete键即可。 2、Spawner Chaining 下图中节点生成了持续2秒的常量流,停止2秒后会重复之前的操作。 2、GPU事件 启用GPU事件,请打开Preferences>Visual Effects,勾选”Experimental Operators/Blocks”。 3、Timeline 如果要控制时间,请在Timeline中创建Visual Effect Activation Track。如果要控制参数,请在Timeline中创建Animation Track。 下面的视频展示了如何设置这些轨道,从而使它们继承来自事件的数值。 下载示例项目 下载示例项目: 结语 文档访问地址: 我们将分享Visual Effect Graph的一些教程,尽请期待。更多Unity更多信息介绍尽在Unity官方中文论坛(UnityChina.cn)! |
分类:unity技术
高清晰渲染管线:专注视觉质量
在《可编程脚本渲染管线SRP》中,我们介绍了可编程脚本渲染管线SRP(Scriptable Render Pipeline)。在Unity 2018.1中,我们已为用户提供了二个渲染管线:轻量级管线Light Weight Pipeline和高清晰渲染管线High Definition Pipeline。在本文中,我们将聚焦高清晰渲染管线或HD RP。
可编程脚本渲染管线SRP项目,Github地址:
https://github.com/Unity-Technologies/ScriptableRenderPipeline
HD RP介绍
- HD RP旨在为开发人员提供实现高清晰视觉效果渲染的工具。它的设计遵循以下三个原则:
- 基于物理的渲染
- 统一且一致连贯的光照
- 独立于渲染路径的特征
基于物理的渲染依赖三大要素:光照、材质和摄像机。光照和材质的效果依赖于物理的相互作用,它们之间应有明确的解耦,能在各种光照条件下获得一致的效果。摄像机决定光照会怎样在屏幕上显示出来。渲染的目标是让艺术家更轻松地实现近乎真实的效果。
统一光照意味着场景中所有对象和参与介质都会得到相同的光照。对象的不透明度、透明度或体积材质不应有任何区别。一个材质必须与任意光照产生正常交互,不管该光照的光源是什么,例如反射探头、区域光等。甚至当被贴花修改时,交互也要正常发生。这样才能得到更为一致的外观效果。
在实时渲染中,有很多渲染通道:延迟/正向、单程/多程、平铺/集群等。在游戏开发中,所选取的渲染路径经常会限制可使用的图形功能。对于HD RP,我们尝试在不同渲染路径下增加相同的一组图形功能。这样的结果是,在选择渲染路径时只需要考虑性能,而不必考虑游戏需要哪些功能。
在HD RP的开发过程中,我们尽可能紧密地遵循这一原则。
HD RP的用途
HD RP针对高端PC和主机开发,可以提供惊艳的高清晰视觉效果。我们希望让小型团队也能使用AAA级图形功能。HD RP运行环境至少需要DX11级别的功能集,并大量使用计算着色器(Compute Shader)。但这样一来,HD RP就不会在功能较弱的平台上运行。HD RP支持的目标API是D3D11、D3D12、GNM(PlayStation 4)、Metal和Vulkan。我们也计划增加对VR支持,但还没在当前可用的预览版中实现。
HD RP具有一套全新的功能和行为,需要再学习和二次开发。我们提供了一个转换工具来将项目从Unity内置模式转为HD RP,但这只会帮助你快速重新设置材质和纹理。所有的光照、后期处理效果、场景设置、图形设置和自定义着色器都需要重做。
最后,HD RP目前仍在预览阶段,这意味它还不适合用于正式创作流程。
光照改进
HD RP拥有一个全新的光照架构:它使用混合延迟/正向-平铺/集群渲染器。这意味着,在场景中有大量光照时,它比Unity内置渲染效果更好。这种新型光照架构更为注重性能。
此外,HD RP还有大量额外的光照属性以及一个全新的光照编辑器。它可以淡化光照,仅影响漫反射光或镜面反射光,或是使用色温来设置光的颜色。聚光灯现在可以控制内部角度,而且可以拥有不同的形状,例如:椎体、立方体或金字塔体。HD RP还支持Colored cookies。
HD RP允许使用实时区域光,当前无阴影或烘焙。例如:柱形光。
最后,光线遵循物理学平方反比衰减,使用的是物理光的单位。光照的控制完全是线性的,去除了Unity内置“Gamma mode”。太阳光强度使用的单位是勒克斯(lux),而点光源和聚光灯所用的单位是流明(Lumen)。
在处理基于图像的光照方面,反射探头在HD RP中得到了更大提升。现在可以使用定向边界方框或球体形状,代理形状(近似场景几何的区域)和影响形状(像素受影响的区域)是分离的,而且加入了很多影响衰减选项(基于法线方向分平面等)。
材质渲染
HD RP有自带的标准着色器,名为受光着色器(Lit Shader)。Lit Shader有不少不错的功能,可以使用比Unity内置渲染中更为丰富的材质。双面选项也可以使用,会自动连接全局照明,加入了很多映射选项,例如单平面和三平面映射。诸如视差遮罩映射或曲面细分等高级功能也已经支持,只需一键便可使用!
不过,加到材质渲染的功能中,最强大的则是其光照模型。
HD RP使用以下BRDF(双向反射分布函数):对镜面反射层使用各向同性多重散射GGX,对漫反射层使用Disney漫反射功能。HD RP与内置Unity在这方面的区别则在于多重散射部分。
金色金属球从平滑(左)到粗糙(右):
默认参数为金属/光滑(Metallic/Smoothness),但也可以在同一着色器中切换为镜面色/光滑(SpecularColor/Smoothness)。
HD RP能增强或替换这个初始模型。它有大量选项可以使用:
增加次表面散射到Disney漫反射中
加入透射效果
加入彩虹效果
加入清漆层GGX
通过调整光照模型能让我们实现多种复杂的外观。
HD RP也能对透明材质使用一组全新选项。例如:通过先背面再前面渲染来帮助排序,用深度后期通道来对景深效果实现透明或其它功能。
基于受光着色器(Lit Shader),HD RP提供了一个分层受光着色器(Layered Lit shader),能够混合多个受光着色器。
HD RP还加入了对贴花的支持。贴花在不透明和透明材质都可以使用,可以正确影响全局光照光照贴图或光照探头的采样。
调试
HD RP中加入的最重要功能是调试工具。调试功能对理解数据创作和性能问题极其重要。
HD RP带有一个全新的自定义调试窗口,能控制调试视图模式和渲染管线设置。这个调试窗口既可以在Unity编辑器中使用,也可以在任意播放器中使用。它现在可以在PlayStation 4等任意目标设备上拥有所有调试功能。
调试窗口允许显示透明材质和不透明材质的任意材质属性,无论它们使用的是延迟渲染路径还是正向渲染路径。
它允许光照调试视图:仅适用漫反射光或仅适用镜面反射光模式。它还能为整个场景修改属性,例如:法线、反射率、光滑度。它也能显示例如动态向量和深度缓冲区的中间渲染目标。它可以根据属性突出对象,例如:突出显示使用光照贴图或曲面细分的对象,还带有NaN检查器等。
它还有一个有意思的模式-颜色选择器模式,用于在应用后期处理功能前读取当前屏幕上的数值或HDR值。调试窗口可以被轻松扩展以支持游戏所需要的任意调试工具,例如:AI或动画调试工具。
新的行为
HD RP具有与 Unity内置的渲染管线完全不同的新行为。
延迟和渲染路径支持的功能是一样的。次表面散射、屏幕空间环境遮罩和贴花的处理功能在二种渲染路径中是一样的。没有必要为使用特定功能选择特定渲染路径。
HD RP使用摄像机相关渲染。这意味着即使远离世界的原点,也可以有不错的渲染精度。这对所有使用HD RP的着色器都有影响。摄像机可以控制所使用的光照架构,可以在同一场景混合使用延迟渲染路径和正向渲染路径,也可以控制为这次渲染使用哪些功能。它还可以禁用烟雾、阴影和后期处理等效果。
为了调整场景设置,还加入了一个基于体积设置的全新系统,它类似当前后期处理效果中的设置。现在可以对每个体积设定场景设置,例如:天空、阳光级联阴影、屏幕空间阴影接触等。还可以通过插入参数在体积间获得平滑的过渡效果。
对于天空和烟雾还增加了新选项,例如:基于高度的烟雾效果或是用天空颜色着色的雾。烟雾会影响透明材质和不透明材质。
最后,HD RP使用一个专用渲染目标分配系统。它能避免在调整屏幕大小时反复重新分配目标。从而避免了在处理动态分辨率时,产生额外的渲染目标分配。
局限
我们仍在开发HD RP,所以它的一些功能还在制作中。HD RP将在 Unity 2018.1作为预览版发布,目前还不适合用来进行正式的创作。
其中一个重要局限是,HD RP还不支持使用Unity粒子系统制作的Lit Particle,只支持Unlit Particle。此外,内置地形系统还存在一些瑕疵。对于所有SRP,之前在Overlay图层渲染的任何对象,例如:镜头光斑特效,都不支持。Grabpass功能也已经不存在了。
未来的开发计划
我们目前专注于增强稳定性和平台支持。但仍会推出一些炫丽的功能,例如:体积光照。
区域光将基于Unity Labs团队的研究进行改进。为了得到更为一致的光照和后期处理效果,基于物理的摄像机是下一步要开发的内容。我们还有多个正在制作的角色渲染工具原型。
结语
HD RP为Unity带来了全新的渲染管线,能够将当下游戏的视效水准提到尽可能的高。但它也有缺点,那就是其学习曲线,因为HD RP和当前内置的渲染管线有显著的区别。
所有这些功能都有一定的复杂性。统一光照和一致光照本身就很难实现,所以拥有强大的调试工具非常重要。对于摄像机相关渲染的使用则需要更多考量。你也可以为HD RP编写自定义着色器,但这需要更多的额外知识。
你也可以在GitHub上跟踪HD RP的开发进展。如果你有任何问题,欢迎访问SRP在 Github上的频道或者在Unity 官方中文论坛(Unitychina.cn)反馈给我们。
Unity UI性能优化技巧
本文将介绍一些提升Unity UI性能的技巧。更多优化技巧,可以观看下方的视频,内容是Unity工程师Ian Dundore在Unite Europe 2017的演讲《使用Unity性能提升技巧》。
https://v.qq.com/x/page/k0704uoak3j.html
划分画布
问题:UI Canvas上有一个或多个元素变化时,会污染整个画布。
画布(Canvas)是Unity UI的基本组件。它会生成网格来呈现放置在画布上的UI元素,当UI元素变化时,它会重新生成网格并向GPU发起绘图调用,从而显示出UI。
生成这些网格会消耗大量性能。需要将UI元素收集到批处理中,从而尽可能减少绘图调用。因为批处理的生成过程性能消耗较大,通常只在必要时候才重新生成。问题在于,当画布上有一个或多个元素变化时,必须重新分析整块画布,才能得到绘制元素的最优方法。
许多用户将整个游戏的UI都放到一块画布,上面摆放了成百上千个元素。因此当修改其中一个元素时,会产生持续数毫秒的CPU使用量飙升情况。
解决方案:划分画布
每块画布上的元素都与其它画布的元素相隔离,所以我们可以使用工具来切分画布,从而解决Unity UI的批处理问题。
你也可以通过嵌套画布来解决,这样能允许设计师创建大型分层UI,而且不必担心不同内容出现在多个画布上。子画布的内容与父画布和同级画布相互隔离。它们会保持自带几何体,执行自己的批处理。
当使用子画布分离画布时,尝试根据画布更新时间来分组。例如:分离动态元素和静态元素。
Graphic Raycaster的最佳用法
问题:Graphic Raycaster有哪些最佳用法?
Graphic Raycaster组件能够将输入内容转换为UI事件,它会把触屏输入转为事件,然后发送给相关UI元素。每个接收输入内容的画布都需要Graphic Raycaster组件,包括子画布。
尽管该组件名为Graphic Raycaster,但它却不是个光线投射器,默认情况下它只会测试UI图形。该组件会获取特定画布上输入信息相关的UI元素集,然后执行交点测试,它会针对Graphic Raycaster的画布上每个交互式UI元素的RectTransform,检查输入事件发生的位置。
解决方案:关闭静态或非交互式元素的Raycast Target。
例如:有个带文字的按钮,关闭该元素的Raycast Target会直接减少Graphic Raycaster每帧进行的交点测试次数。
问题:有时候Graphic Raycaster会充当光线投射器使用。
如果将画布上的渲染模式设为世界空间摄像机(Worldspace Camera)或屏幕空间摄像机(Screen Space Camera),此时可以设置阻挡遮罩(Blocking Mask)。
阻挡遮罩决定光线投射器是通过2D物理还是3D物理投射光线,从而了解特定物理对象是否阻挡用户与UI交互。
解决方案:通过2D或3D物理投射光线会消耗不少性能,所以要谨慎使用该功能。
尽量减少Graphic Raycaster的数量,不要将Graphic Raycaster添加到非交互式UI画布上,因为这样做无法检查交互事件。
避免使用Camera.main
问题:世界空间画布需要了解交互事件来自哪个摄像机。
当设置画布进行渲染时,不管该画布是在世界空间还是摄像机的屏幕空间,都可以指定用于为UI中Graphic Raycaster生成交互事件的摄像机。渲染模式为“Screen Space – Camera”的画布需要使用该设置,该设置名为“Render Camera”。
然而在渲染模式为“World Space”的画布上,该设置是可选的,名为“Event Camera”。
如果将世界空间画布的Event Camera字段留空,这不意味着该画布不会接收事件。它会使用游戏的主摄像机。为了确定哪个摄像机是主摄像机,该画布会访问Camera.main属性。
根据Unity所使用的代码路径,每帧中每有一个Graphic Raycaster和世界空间画布,该画布会访问7到10次Camera.main。每次访问Camera.main都会调用Object.FindObjectWithTag。这个做法在运行时并不合适。
解决方案:避免使用Camera.main
缓存摄像机的引用,然后创建系统来跟踪主摄像机。如果使用世界空间画布,要指定Event Camera,不要将该属性留空。如果需要修改Event Camera,编写代码来更新Event Camera属性。
避免使用布局分组
问题:每个影响布局的UI元素都会至少执行一次GetComponents调用。
当修改布局系统的一个或多个子元素时,会使布局变脏。修改后的子元素会使拥有该元素的布局系统(Layout System)无效化。
简单介绍一下布局系统:布局系统是一组连续的布局分组(Layout Group),它们在布局元素(Layout Element)之上。布局元素不只是名为Layout Element的组件,它们还包括UI图像、文字和Scroll Rect组件,而且Scroll Rect同时也是布局分组。
回到问题本身,每个使布局变脏的UI元素都会至少执行一次GetComponents调用,该调用会在布局元素父对象上寻找有效的布局分组。找到有效布局分组后,它会继续遍历Transform层级,直到停止寻找分组或是到达层级的根部分,无论先满足哪个条件都会停止寻找过程。因此。每个布局分组会给每个子布局元素的改变过程添加一次GetComponents调用,使嵌套布局分组的性能变差。
解决方案:避免使用布局分组。
使用锚点进行比例布局。在拥有动态元素数量的活跃UI上,考虑编写代码来计算布局,仅在需要时运行该代码,而不是每次发生改变的时候。
巧妙地聚集UI对象
问题:用错误的方法聚集UI对象。
通常情况下,用户通过重置父对象来聚集UI对象,然后再禁用对象,但这样会造成不必要的污染。
解决方案:首先禁用对象,然后将其父对象重置为对象池。
这样操作仅会改变一次原有的层级,但在重置父对象时,要避免二次改变原有的父对象,也不要改变新的层级。如果要从对象池移除对象,首先重置它的父对象,然后更新数据,再启用该对象。
如何隐藏画布
问题:如何隐藏画布?
有时需要隐藏UI元素和画布,要怎样高效完成该任务呢?
解决方案:禁用Canvas组件。
禁用Canvas组件会阻止画布向GPU发起绘图调用,所以该画布不再可见。然而,此时该画布不会丢弃它的顶点缓冲区,它会保留所有网格和顶点,当重新启用时不会触发重构过程,它只会重新绘制画布内容。
此外,禁用Canvas组件不会触发Canvas层级上性能消耗较大的OnDisable/OnEnable回调。禁用子组件时要小心,注意它是否运行性能消耗较大的每帧代码。
UI元素上Animator的最佳用法
问题:如何在UI上使用Animator?
Animator每帧都会改变元素,即使动画中的数值没有变化。Animator没有空指令检查。
解决方案:
只在频繁变化的动态元素上加入Animator。对于很少变化的元素,或是仅响应事件时才变化的元素,请自行编写代码或补间系统,你可以在Asset Store资源商店找到许多补间系统插件。