MENU 导航菜单

URP系列教程 | 如何使用多个Renderer Feature来实现角色透视效果

奇正资讯 > Unity资讯 更新时间:2022/1/19

我们知道 URP 的 Renderer Feature 支持用户向 URP Renderer 添加额外的渲染通道,从而允许我们进行自定义渲染的顺序、渲染的对象或者材质等。使用 Renderer Feature,我们可以实现多 pass 的效果,比如物体的描边效果、以及自定义一些后处理效果等等,我今天就手把手带大家使用多个 Renderer Feature 来实现角色的透视效果


具体是一个什么样的效果呢?如下图所示我们使用 URP 的 Renderer Feature 实现当角色位于 GameObjects(建筑物)背后时,Unity 会使用不同的材质绘制角色,从而表现出一种透视的视觉效果。


图片


首先我们创建一个 URP Asset,将其重命名为 OcclusionDemoCompleted(当然这个名字你可以自己发挥),然后将其赋给 Project Settings > Graphics > Scriptable Render Pipeline Settings(如下图所示)。


图片


接着创建一个材质 Dither,并使用 Shader Graph 创建一个屏幕扰动的 Shader,并将其命名为 ScreenDitherShader。颜色我设置为黄色,把这个 Shader 赋给这个材质 Dither,当角色位于 GameObject 后,我们后面会用 Renderer Feature 调用这个材质 Dither 去替换角色本身的材质 MAT_Mage_Blue。


图片

这个案例里我们实现使用了两个 Render Object Renderer Feature:一个用于绘制位于场景中其他游戏对象(如建筑)后面的角色部分,另一个用于绘制位于场景中其他游戏对象(如建筑)前面的角色部分。


我们先来创建用于绘制在建筑后面时角色部分的 Renderer Feature


首先我们选择之前创建的 UnityOcclusionRenderer,在 Inspector 中,单击 Add Renderer Feature 并选择 Render Objects。选择名称字段并输入新渲染器功能的名称 Dither(因为在建筑背后,角色表现出扰动的效果所以名字命名为Dither)。


图片


我们使用 Layer 层来过滤要渲染的游戏对象,创建一个新的 Layer 层,并将其重命名为 Character。


在 Dither Renderer Feature  中,在 Filters > Layer Mask 中,选择 Character。这样的话,Dither Renderer Feature 仅渲染这个 Layer 中的游戏对象 Character。然后在 Overrides > Material 中,选择 Dither 。那么 Dither Renderer Feature 就会使用设置的材质覆盖游戏对象的正常的材质。


图片


我们的预期效果是仅当角色位于其他游戏对象之后时,Dither Renderer Feature 才使用 Dither 材质渲染角色。所以我们要进行深度检测 Depth Test (深度信息是用来决定哪些像素离摄像机更近,我们这里使用深度测试DepthTest来决定当前像素是否被绘制),我们勾选“Depth”复选框,并将“Depth Test 深度测试”属性设置为“Greater”(大于)。


这样设置也就意味着,Dither Renderer Feature 仅在角色的深度值(深度值的范围在0~1之间,值越小表示越靠近摄像机,值越大表示越远离摄像机)大于另一个物体的深度值(也就意味着角色位于另一个游戏对象后面时)才使用材质渲染角色。


图片


但是现在我们遇到一个问题是:因为角色的某些部分也会遮挡角色本身。所以 Dither 材质会替换角色的某些部分。如下右图所示。这不是我们预期的结果。


图片


为什么会发生这种情况呢?执行 Dither Renderer Feature 时,Unity 使用深度测试属性中指定的条件执行深度测试。与截图中所示的情况类似,较大的胶囊遮挡了较小胶囊的一部分,并且对于较小胶囊的那部分通过了深度测试。那么 Renderer Feature 会覆盖该部件的材质。我们的角色的遮挡也类似;所以出现了这种自透明效果情况的发生。


图片


那么我们要怎么解决这个问题?接下来我们就来看下如何避免此类行为确保 Unity 使用适当的材质绘制角色的所有部分。


图片 在 URP Renderer 中,在Filtering > Opaque Layer Mask 中,清除 Character 图层旁边的复选标记。现在 Unity 不会渲染角色,除非它位于 GameObject 后面。但这个还不是我们需要的效果(如下图所示)。


图片


图片 然后我们添加一个新的 Renderer Feature,并将其命名为 Character. 这就是我们前面提到的那个用于绘制位于场景中其他游戏对象(如建筑)前面的角色部分的 Renderer Feature 。


图片 在 Character Renderer Feature 中,在 Filters > Layer Mask 中,选择 Character 图层(因为两个Renderer Feature 都是渲染角色的)。


我们看下效果发现:即使角色在游戏对象后面,Unity 也会使用材质渲染角色。


图片


为什么会发生这种状况呢?发生这种情况是因为在 Dither Renderer Feature 中勾选了 Write Depth( Write Depth:定义Renderer Feature是否在渲染对象时更新深度缓冲区)将深度值更新重写深度缓冲区。角色在建筑背后被 Dither 材质渲染也就是说角色的深度值已经变化。这个时候在执行 Character Renderer Feature 当然会被再次渲染掉。


所以我们要做就是取消勾选 Write Depth 选项。不需要重写深度缓冲区。


图片

图片 在 Overrides > Depth 中,清除 Write Depth 复选框。Dither Renderer Feature 将不会更改深度缓冲区,并且当角色位于建筑游戏对象之后时, Character Renderer Feature 也不会绘制角色。


到这里的话,当角色在建筑 GameObjects 之后时,Unity 会使用 Dither Material 绘制角色轮廓的效果就已经完成。


图片


Ok,到这里的话,我们使用两个 Renderer Feature 实现了角色的透视效果。


本文转载自unity公众号

下一篇:Unity与现代汽车公司合作构建新型元宇宙平台,加速智能制造 上一篇:想学Unity不知从何下手?这两个宝藏学习场所,你居然还不知道