unity绘制管道_Unity可编程渲染管线(SRP)教程:一、自定义管线

控制渲染

创建pipeline asset 和 instance.

剔除、过滤、排序、渲染.

保持内存清洁.

提供良好的编辑体验.

这是Unity scriptable render pipeline系列教程的第一部分。本教程假设你首先通过了Basics系列教程和Procedural Grid教程。Rendering系列的头几部分也很有帮助。

本教程使用Unity 2018.3.0f2完成。创建一个Pipeline

渲染任何东西Unity都需要明确哪些形状、何处、何时以及使用什么设置。这些可以变得非常复杂取决于涉及到多少效果。光源、阴影、半透明、图像效果、体积效果以及等等都需要用正确的顺序处理,以获得最终的图像。这个过程被称之为渲染管线。

Unity 2017 支持两种预定义渲染管线,一种是前向渲染,另一种是延迟渲染。也仍然支持Unity 5中引入的旧延迟渲染方法。这种管线是固定的。你可以开启、关闭或者覆盖管线中某些部分,但不可以彻底偏离它的设计。

Unity 2018 添加了可编程渲染管线的支持,使得从头设计管线成为可能,尽管你仍然需要依赖Unity来完成许多单独的步骤,例如剔除。Unity 2018引入了两种使用这种新方法的管线,轻量级渲染管线和高分辨率渲染管线。两种管线仍处于预览阶段并且可编程渲染管线API依然被标记为实验技术。但是在这一点上对我们来说足够稳定可以继续创建并创建我们自己的管线。

在这个教程中我们会设置一个绘制Unlit图形的最小渲染管线。一旦起作用了,我们可以在之后的教程中扩展我们的管线,添加光照、阴影、以及更多的高级特性。

1.1 项目设置

打开Unity 2018并创建一个新项目。我使用的是Unity 2018.2.9f1,但是任何2018.2版本或者更新版应该也可以使用。创建一个Standard 3D项目并禁用analytics。我们会创建我们自己的管线,所以不选择任何管线选项。

项目打开后,由Window/Pakage Manager打开包管理器,并且移除所有默认包含的包,因为我们不需要它们。只保留不可以被移除的Package Manager UI。初始的项目

我们要在线性色彩空间下工作,但是Unity 2018依然默认使用gamma空间。所以由Edit/Project Setting/Player到player setting中,然后将Other Setting部分中的色彩空间切换到Linear。线性色彩空间

我们需要几个简单的材质去测试我们的管线。我创建了四种材质。第一种,默认的standard opaque材质带有红色albedo。第二种,一样的材质但是Rendering Mode设置为Transparent以及蓝色的albedo带有减少的alpha。第三种,使用Unlit/Color shader并且颜色设置为黄色的材质。最后一种使用Unlit/Transparent shader并不做任何改变,因此显示为纯白色。测试材质

使用一些object填充场景,让它们用完所有的四种材质。

场景显示四种材质

1.2 Pipeline Asset

现在,Unity使用默认的前向渲染管线。要使用自定义管线,我们需要在grahics settings中选择,可以由Edit/Project Setting/Graphics找到。

使用默认管线

要设置我们自己的管线,我们需要分配一个pipeline asset到Scriptable Render Pipeline Settings字段。这类asset需要扩展RenderPipelineAsset,这是一种ScriptableObject类型。

为我们的自定义pipeline asset创建一个新脚本。我们将简单地命名我们的管线为My Pipeline。这个asset类型将因此成为MyPipelineAsset并且需要扩展RenderPipelineAsset,它被定义在UnityEngine.Experimental.Rendering命名空间中。using UnityEngine;using UnityEngine.Experimental.Rendering;public class MyPipelineAsset : RenderPipelineAsset {}它会一直在experimental命名空间中吗?它会在某个时刻被移出experimental命名空间,到UnityEngine.Rendering或者其他命名空间。当这种情况发生时,只需要更新using语句,除非API也发生了改变。

pipeline asset的主要目的是给Unity一个途径去获取负责渲染的管线对象实例。asset它本身只是一个句柄和存放管线设置的地方。我们目前还没有任何设置,所以我们要做的是给Unity一个途径去获取我们的管线对象实例。这个通过重载InternalCreatePipeline方法来实现。但是我们还没有定义我们的管线对象,所以此时我们将仅返回null。

InternalCreatePipeline返回值类型是IRenderPipeline。类型名的I前缀表示它是接口类型。public class MyPipelineAsset : RenderPipelineAsset {protected override IRenderPipeline InternalCreatePipeline () {return null;}}什么是接口?接口就像一个类,除了定义一个功能合同且不提供它的实现。它只定义属性、事件、索引器和方法签名,它们都是被定义公开的。任何扩展接口的类型都要求包含接口定义的实现。惯例是在接口名前加个I前缀。因为接口不包含具体的实现,所以类甚至结构体可以扩展多个接口。如果多个接口碰巧定义了相同的东西,它们只是同意功能应该存在。在类中是不可以的即使是抽象类,因为这个可能导致实现冲突。

现在我们需要为我们的项目添加一个这种类型的asset。要实现这点,添加CreateAssetMenu特性到MyPipelineAsset。[CreateAssetMenu]public class MyPipelineAsset : RenderPipelineAsset {}

这在Asset/Create菜单中添加了个入口。让我们整理一下,把他放到Rendering的子菜单中。我们通过设置特性的menuName属性为Rendering/My Pipeline来完成。这个属性在可以被直接设置在特性类型之后的圆括号中。[CreateAssetMenu(menuName = "Rendering/My Pipeline")]public class MyPipelineAsset : RenderPipelineAsset {}

使用新菜单项添加这个asset到项目,命名为My Pipeline。Pipeline asset及其脚本

然后把它分配到Scriptable Render Pipeline Settings。

使用中的Asset

我们现在已经替换了默认的管线,更改了一些东西。首先,graphics setting中的大量选项不见了,Unity也在信息面板中提到了这些设置。其次,我们绕过了默认管线并不提供有效的替换,因此不会进行任何渲染。尽管,场景窗口仍然显示天空盒,但是游戏窗口、场景窗口和材质预览不再起作用,如果你由Window/Analysis/Frame Debugger打开帧调试器,并且启用它,你会看见确实没有在游戏窗口中绘制任何东西。

1.3 管线实例

创建一个有效的管线,我们需要提供一个实现IRenderPipeline并负责渲染流程的对象实例。所以为此创建一个类将其命名为MyPipeline。using UnityEngine;using UnityEngine.Experimental.Rendering;public class MyPipeline : IRenderPipeline {}

尽管我们可以实现由自己IRenderPipeline,但是更方便的是扩展RenderPipeline类。这个类型已经提供一个IRenderPipeline我们可以自己构建的实现。public class MyPipeline : RenderPipeline {}

现在我们可以在InternalCreatePipeline中返回一个MyPipeline的新实例。这意味着我们在技术上有了一个有效的管线,尽管这依然不能渲染任何东西。protected override IRenderPipeline InternalCreatePipeline () {return new MyPipeline();}

2. 渲染

管线对象负责渲染每一帧。Unity会根据上下文以及激活的相机调用管线的Render方法。这是针对游戏窗口的,也适用于场景窗口和编辑器中的材质预览。这需要我们适当地配置,找到需要渲染的内容,并且按正确的顺序处理每个操作。

2.1 上下文

RenderPipeline包含了定义在IRenderPipeline接口中的Render方法的实现。它第一个参数是渲染上下文,这是ScriptableRenderContext结构,作为native code的外在表现。这第二个参数是一个包含所有需要渲染的相机的数组。

Ren

你可能感兴趣的:(unity绘制管道)