目录
可编程渲染管线是一个可以通过代码控制渲染的方式的管线。
传统Unity提供了一系列的内置管线供我们使用。包括前向渲染和延迟渲染。这些渲染方式是传统渲染黑盒子的缺点:
SRP Core API 解决了上面描述的问题。其将渲染流程从原来的黑盒转向可控制、预制件、可编程的方向。
SRP Asset本身是一个ScriptableObject,我们可以对其进行保存和版本控制。在GraphicsSetting中进行设置,Unity会使用SRP提供的渲染设置。SRP Asset提供了配置渲染管线的接口,当Unity实现第一次渲染的时候,其会调用InternalCreatePipelineCreatePipeline,Asset会返回一个SRP Instance。
ScriptableObject : 这是一个用于存储数据的容器。通常为了避免复制数据而占用存储空间使用。需要作为Asset存储在项目中,不能附加在游戏物体上,
[ExecuteInEditMode]
public class BasicAssetPipe : RenderPipelineAsset
{
public Color clearColor = Color.green;
#if UNITY_EDITOR
// Call to create a simple pipeline
[UnityEditor.MenuItem("SRP-Demo/01 - Create Basic Asset Pipeline")]
static void CreateBasicAssetPipeline()
{
var instance = ScriptableObject.CreateInstance<BasicAssetPipe>();
UnityEditor.AssetDatabase.CreateAsset(instance, "Assets/BasicAssetPipe.asset");
}
#endif
protected override RenderPipeline CreatePipeline()
{
return new BasicPipeInstance(clearColor);
}
}
SRP Asset控制配置,但是SRP Instance是真正的渲染的切入点,渲染的逻辑都在SRP Instance中。SRP Instance中包括一个Render function,此方法包括两个变量:ScriptableRenderContext(Command Buffer用于排列渲染相关操作)、Camera(需要渲染的摄像机)。
public class BasicPipeInstance : RenderPipeline
{
private Color m_ClearColor = Color.black;
public BasicPipeInstance(Color clearColor)
{
m_ClearColor = clearColor;
}
protected override void Render(ScriptableRenderContext context, Camera[] cameras)
{
// clear buffers to the configured color
var cmd = new CommandBuffer();
cmd.ClearRenderTarget(true, true, m_ClearColor);
context.ExecuteCommandBuffer(cmd);
cmd.Release();
context.Submit();
}
}
SRP使用Unity中的CommandBuffers提供相关操作,CommandBuffers中的顺序是根据context传入的数据排序。SRP渲染最后一步需要调用context.Submit()方法,这一步执行render context中相关指令。
SRP渲染使用了延迟执行的方法。如果我们创建了一系列指令并执行它们。用于创建指令的的对象叫ScriptableRenderContext作为一个参数传给Render方法。
Culling包含:
Unity开始渲染第一步是计算哪些可以渲染。这包括选择一个摄像机和进行剔除操作。提出操作返回一个被摄象机渲染的游戏物体和光照的列表。SRP将在之后的渲染管线中使用这些游戏物体。SRP提供了很多关于提出的相关API。
//Parameters controlling culling process in CullingResults
ScriptableCullingParameters cullingParams;
Camera.main.TryGetCullingParameters(out cullingParams);
//doing culling for each camera
CullingResults cullingResults = new CullingResults();
cullingResults = context.Cull(ref cullingParams);
在SRP中draw需要在culling步骤完成之后进行。
在渲染管线中可配置的部分很多,有一些我们需要在工作之前进行确认:
比如2D横板过关和3D高画质PC第一人称游戏有很大的不同约束,在渲染管线中有很大的不同。以下是一些具体的选项:
实例1:过滤:Render Buckets and Layers
无光照,渲染一些不透明的物体
游戏物体有很多的类别,Unity使用队列的方式对其渲染。这些队列来自Unity存放GameObjects的buckets。当SRP渲染场景的时候,可以指定buckets的范围。
在buckets,可以使用标准的Unity Layers进行过滤。
var opaqueRange = new FilteringSettings();
//FilteringSettings.renderQueueRange : Render objects whose material render queue in inside this range
//这里的渲染队列在[0,GeometryLast]之间是为不透明对象,在[GeometryLast,5000]之间被视为半透明对象。
opaqueRange.renderQueueRange = new RenderQueueRange(0, (int)RenderQueue.GeometryLast);
//layerMask - Only render objects in the given layer mask
opaqueRange.layerMask = ~0;
实例2:绘制设置:物体如何被绘制出来的
通过前面的filtering和culling的过程,SRP决定了那些是需要渲染的对象,但是还需要进行如何绘制的设置.SRP提供了大量的可选择配置来渲染那些通过了过滤的游戏物体。用于配置的结构体叫做 DrawRenderSettings:允许我们进行配置:
//Setting for DrawRenderers.describes how to sort visible objects are sorted and which shader passes to use.
//SortingSettings - This struct describes the methods to sort objects during rendering.
var ds = new DrawingSettings(new ShaderTagId("Opaque"), new SortingSettings(Camera.main));
ds.enableInstancing = true;
//what kind of per-object data to setup during rendering. pass lightprobe and lightmap data to each renderer
ds.perObjectData = PerObjectData.LightProbe | PerObjectData.Lightmaps;
创建一个DrawingSettings对象,并设置这个对象的一些属性。
在完成上面的两个步骤后就可以进行绘制了,将
添加一个Free Camera组件,可以让摄像机通过键盘和鼠标进行简单的的移动,在Play Mode下进行移动和旋转。
Camera Switcher组件可以定义一系列相机,然后在Play Mode中通过Debug Window在这些相机之间进行切换。