目录
- 开始
SRP解决了什么问题
SRP Asset
SRP Instance
SRP Context - SRP 中的渲染
Culling
Drawing - SRP 中的 XR
- 摄像机组件
Free Camera
Camera Switcher
问题 传统Unity提供了一系列的内置管线供我们使用。包括前向渲染和延迟渲染。这些渲染方式是传统渲染黑盒子的缺点:
- 它们只能按照他们本身设计的程序执行
- 它们很一般,它们需要做每一件事,而不能掌控任何流程
- 它们不可配置。只能在预设的位置注入一些指令
- 拓展性和可修改性有限,内部较小的修改可能导致外部较大的变化
- 由于改变破坏项目的行为产生Unity无法修复的Bug
SRP Asset 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();
UnityEditor.AssetDatabase.CreateAsset(instance, "Assets/BasicAssetPipe.asset");
}#endifprotected override RenderPipeline CreatePipeline()
{
return new BasicPipeInstance(clearColor);
}
}
SRP Instance 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 Context SRP渲染使用了延迟执行的方法。如果我们创建了一系列指令并执行它们。用于创建指令的的对象叫ScriptableRenderContext作为一个参数传给Render方法。
SRP中的Culling Culling包含:
- 视锥剔除:只计算在摄像机近裁剪面和远裁剪面之间的游戏物体
- 遮挡剔除:计算那些物体被遮挡了,并将被遮挡的物体进行剔除。
//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中的 Drawing 在SRP中draw需要在culling步骤完成之后进行。
在渲染管线中可配置的部分很多,有一些我们需要在工作之前进行确认:
- 渲染管线的目标硬件
- 想实现的特殊视觉效果
- 项目的类型
- HDR vs LDR
- Linear vs Gamma
- MSAA vs Post Process anti-aliasing
- Physically-based Materials vs Simple Materials
- Lighting vs No Lighting
- Lighting technique
- Shadowing technique
无光照,渲染一些不透明的物体
游戏物体有很多的类别,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:允许我们进行配置:
- Sorting - 渲染游戏物体的顺序,比如从前向后或从后向前
- Per-Renderer flags - 那些内置的设置要Unity传给Shader,这包括像预置的光线探针、预置的光线贴图
- Rendering flags - SRP batching的算法,像instancing 或者 non-instancing
- Shader Pass - 当前渲染批次使用哪个Shader pass
//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 = https://www.it610.com/article/PerObjectData.LightProbe | PerObjectData.Lightmaps;
创建一个DrawingSettings对象,并设置这个对象的一些属性。
在完成上面的两个步骤后就可以进行绘制了,将
Free Camera 添加一个Free Camera组件,可以让摄像机通过键盘和鼠标进行简单的的移动,在Play Mode下进行移动和旋转。
Camera Switcher 【#|Unity - 可编程渲染管线(Scriptable Render Pipeline)】Camera Switcher组件可以定义一系列相机,然后在Play Mode中通过Debug Window在这些相机之间进行切换。
推荐阅读
- 数据结构和算法|LeetCode 的正确使用方式
- #|7.分布式事务管理
- #|算法设计与分析(Java实现)——贪心算法(集合覆盖案例)
- #|算法设计与分析(Java实现)—— 动态规划 (0-1 背包问题)
- #|阿尔法点亮LED灯(一)汇编语言
- #|Multimedia
- #|ARM裸机开发(汇编LED灯实验(I.MX6UL芯片))
- 基础课|使用深度优先搜索(DFS)、广度优先搜索(BFS)、A* 搜索算法求解 (n^2 -1) 数码难题,耗时与内存占用(时空复杂度)对比(附((n^2 - 1) 数码问题控
- #|学习笔记 | Ch05 Pandas数据清洗 —— 缺失值、重复值、异常值
- win10|搏一搏 单车变摩托,是时候捣鼓一下家中的小米电视机啦。