概述
文章目录
- 可编程渲染管线 Scriptable Render Pipeline
- 什么是可编程渲染管线SRP
- 什么是SRP Core
- SRP入门 Getting Started
- 概述
- SRP Asset
- SRP Instance
- SRP要解决的问题
- 问题
- 解决方案
- SRP Asset
- SRP Asset 例子
- SRP Instance
- 基础管线 A basic pipeline
- SRP Context
- 用SRP渲染 Rendering with SRP
- 裁剪 Culling
- 绘制 Drawing
- 过滤:渲染队列和层 Filtering: Render Buckets and Layers
- 渲染设置 Draw Settings: How things should be drawn
- 绘制 Drawing
- XR应用SRP (Virtual Reality)
- 摄像机组件 Camera Components
- Free Camera
- Camera Switcher
可编程渲染管线 Scriptable Render Pipeline
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tUm1QF1U-1581473895125)(https://blogs.unity3d.com/wp-content/uploads/2018/01/image5_rs.png)]
什么是可编程渲染管线SRP
Scriptable Render Pipeline(SRP),提供一组特性,让你可以完全的控制Unity的渲染流程,并提供工具创建流行的,真实的图形。
SRP允许通过编写C#代码来控制每帧的渲染。不像内建的渲染管线是一个渲染的黑盒子,SRP让你可以看到和精确控制渲染过程。
Unity也提供了2种预建的SRP,可以在项目种作为自定义SRP的基础:
- Universal Render Pipeline 提供了从手机平台到高端主机和PC平台的图形渲染
- High Definition Render Pipeline 利用PBR技术,为兼容Compute Shader的显卡平台提供逼真的图形渲染。
与其从头开始实现自己的SRP,建议基于URP或HDRP根据自己的需求进行修改。
什么是SRP Core
SRP Core 是一组API,将内部渲染和配置暴漏给你,这可以让你精确控制渲染如何工作。
SRP API 提供了一组与一些Unity结构相似的接口:
- Lights
- Materials
- Cameras
- Command Buffers
SRP 改变的是与Unity交互的方式。基于效率的考虑,当你实现自己的SRP时,需要一系列的Renderer,而不是单独实现某个独立的组件。
SRP入门 Getting Started
概述
从上层来看,SRP可以被分成2部分,SRP Asset 和 SRP Instance。当实现自己的SRP时,需要实现这两部分。
SRP Asset
SRP Asset 是用来为管线存储需要的配置数据,包括:
- Game Object 是否可以投射阴影
- 使用哪个级别的Shader Quality
- 阴影距离
- 默认的材质配置
SRP Instance
SRP Instance 是真正执行渲染的类。当Unity发现使用了SRP,它会检查当前的SRP Asset 并请求它提供渲染实例,而SRP Asset 必须要返回一个包含 Render 函数的实例。通常该Instance也要将SRP Asset的一些配置缓存下来方便使用。
Instance 缓存了管线的配置,在Render方法中,Unity可以执行下列行为:
- 清理帧缓存 Clearing the framebuffer
- 执行场景裁剪
- 渲染一组游戏对象
- 执行framebuffer之间的拷贝
- 渲染阴影
- 执行后效
SRP要解决的问题
渲染管线是一系列的步骤来将对象绘制到屏幕上,而SRP则是将这些步骤交给你可以编程进行控制。
问题
Unity提供了一些内建的管线使用。包括适用于移动平台和VR的前向渲染,以及适用于高端的延迟着色。这些解决方案像个黑盒,方便的同时有以下问题:
- 它们只能按照Unity设计的来工作
- 它们是通用的,意味着它们要做所有的事情,同时意味着所有事情都不是最优的
- 它们的可配置度很低,是黑盒工具,仅可以在预定义的点注入渲染指令
- 扩展和修改非常容易导致错误,因为内部一点小改动,都会导致对外部的很大影响
- Unity对一些BUG难以进行修复,因为这些修复可能会导致现有项目无法工作
解决方案
SRP的推出就是为了解决上面的问题。将内建的渲染过程改为可以针对每个项目编程控制的。
SRP Asset
SRP Asset 包含了一组接口用来对渲染管线进行配置。当Unity第一次渲染时,会调用其 InternalCreatePipeline
方法创建渲染实例。
SRP实际上是一个 ScriptableObject,所以它是一个资源文件,可以进行版本控制。可以在Project窗口中创建SRP Asset,也可以通过脚本创建并通过AssetDatabase API进行保存。
在ProjectSettings>Graphics中设置启用自己的SRP Asset。
除了返回渲染实例和处理配置数据外,还可以通过SRP Asset提供一些辅助函数:
- 创建3D对象时的默认材质
- 创建2D对象时的默认材质
- 创建粒子时的默认材质
- 创建地形时的默认材质
这主要是为了让编辑器正确工作。如果希望在新的管线的编辑器像Unity的管线编辑器一样工作,则需要实现这些。
SRP Asset 例子
Asset 包含了一些渲染属性,以及返回一个渲染实例来渲染场景。如果设置改变,则Unity会销毁渲染实例,并创建新的,在下一帧进行渲染。
下面是一个SRP Asset 的例子。包含了SRC Instance 清除屏幕时用的颜色,以及在编辑器中创建SRC Asset的逻辑,创建完后可以在Graphics设置窗口中设置。
[ExecuteInEditMode]
public class BasicAssetPipe : RenderPipelineAsset
{
public Color clearColor = Color.green;
#if UNITY_EDITOR
[MenumItem("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 IRenderPipeline InternalCreatePipeline()
{
return new BasicPipeInstance(clearColor);
}
}
SRP Instance
SRP Asset 控制渲染配置,SRP Instance 则时渲染入口。当开发SRP时,需要实现该类,并在该类中实现所有的渲染逻辑。
最简单的,SRP Instance 只需要包含一个接口:Render。可以理解为这时空白的画板,可以在里面自由地用任何方式进行渲染。Render 函数有两个参数:
- ScriptableRenderContext 是一个指令缓存,可以推入渲染操作来执行。
- 一组渲染用的摄像机。
基础管线 A basic pipeline
前面的SRP Asset返回的Rendering Instance在下面实现:
public class BasicPipeInstance : RenderPipeline
{
private Color m_ClearColor = Color.black;
public BasicPipeInstance(Color clearColor)
{
m_ClearColor = clearColor;
}
public override void Render(ScriptableRenderContext context, Camera[] cameras)
{
base.Render(context, cameras);
// 将屏幕清理成配置的颜色
var cmd = new CommandBuffer();
cmd.ClearRenderTarget(true, true, m_ClearColor);
context.ExecuteCommandBuffer(cmd);
cmd.Release();
context.Submit();
}
}
管线仅简单的用SRP Asset配置的颜色,清理屏幕。需要注意几点:
- SRP 使用Unity的CommandBuffer来执行许多操作(这里是ClearRenderTarget)。
- SRP 用传进来的context执行CommandBuffers。
- 最后,要调用context.Submit,来执行我们添加到context指令队列中的指令。
Render函数是我们进行渲染的地方,在这里我们要执行裁剪,过滤,改变renter target,绘制,等。
SRP Context
SRP渲染使用延迟执行的概念。我们建立了一个指令列表,并执行该列表。指令列表即Render参数传进来的ScriptableRenderContext对象context。
当指令添加到context队列中后,可以调用它的Submit来提交这些指令,这些指令会被组合成一个Command Buffer并执行。
ScriptableRenderContext的API可以参考:API documentation.
用SRP渲染 Rendering with SRP
裁剪 Culling
裁剪负责找出哪些需要被渲染到屏幕上。在Unity中,裁剪包括:
- Frustum Culling 视锥体裁剪。找出所有在摄像机近裁剪面和远裁剪面之间的对象。
- Occlusion Culling 遮挡剔除。找到被其它对象遮挡的对象,并将其排除出渲染对象列表。详细参考:Occlusion Culling.
Unity开始渲染后,第一件要做的事情就是要决定哪些对象需要被渲染,使用相关的摄像机进行裁剪。裁剪操作返回一个该摄像机需要渲染的对象和光源列表。SRP在之后的渲染中使用这些数据。
SRP提供了一些API用来进行裁剪,通常像下面:
ScriptableCullingParameters cullingParams;
// 从摄像机获取裁剪参数
if(!CullResults.GetCullingParameters(camera, stereoEnabled, out cullingParams))
continue;
// 如果需要,可以修改裁剪参数
cullingParams.isOrthographic = true;
// 创建保存裁剪结果的结构体
CullResults cullResults = new CullResults();
// 执行裁剪
CullResults.Cull(ref cullingParams, context, ref culResults);
// 下面开始渲染
// render...
绘制 Drawing
SRP中,裁剪完成后,就可以将相关的游戏对象列表绘制到屏幕了。
可以有很多种方法进行渲染,因此在实现之前,要先决定绘制策略。这些策略包括:
- 要执行渲染的硬件
- 要达到的渲染效果
- 项目的类型
例如,移动端2D卷轴游戏和3D高端PC第一人称游戏是完全不同的渲染管线。下面是一些需要做出的选择的例子:
- HDR vs LDR 高动态范围光 vs 低动态范围光
- Linear vs Gamma 线性 vs 伽马 空间
- MSAA vs Post Processing anti-aliasing 多重屏幕抗锯齿 vs 后效抗锯齿
- Physically-based Materials vs Simple Materials 基于物理的材质 vs 简单材质
- Lighting vs No Lighting 是否有光照
- Lighting Technique 采用哪种光照技术
- Shadow Technique 采用哪种阴影技术
这些决策可以帮助我们在实现管线时决定应该有哪些限制。
下面的例子简单的渲染了一些不带光照,不透明的对象。
过滤:渲染队列和层 Filtering: Render Buckets and Layers
通常,每个Game Object都有特定的类型,不透明,半透明,次表面,等。Unity在渲染时将对象根据其类型,放入对应的队列来进行管理(根据对象的材质)。SRP渲染时,需要指定要渲染哪些队列。(原文是桶,感觉队列更容易理解)
除了队列,还可以用Unity的层Layer来进行过滤。
// 获取不透明过滤器对象
var opaqueRange = new FilterRenderersSettings();
// 设置不透明渲染队列范围
opaqueRange.renderQueueRange = new RenderQueueRange()
{
min = 0,
max = (int)UnityEngine.Rendering.RenderQueue.GeometryLast,
};
// 包括所有的层
opaqueRange.layerMask = ~0;
渲染设置 Draw Settings: How things should be drawn
通过裁剪和过滤确定了哪些对象将要被渲染,然后需要确定如何渲染它们。SRP提供了多种选项来配置对象如何进行渲染。配置渲染可以通过结构体 DrawRenderSettings
。可以进行如下的配置:
- Sorting 排序,以什么样的顺序进行渲染,比如从前向后,或从后向前(基于摄像机距离)。
- Per-Renderer flags 哪些内建的设置需要传递给shader,包括像逐对象的光照探针,逐对象的光照贴图。
- Rendering flags SRP使用哪种算法合批,比如instancing或non-instancing。
- Shader Pass 当前的DrawCall使用哪个Shader Pass。
// 创建渲染设置
// 需要shader pass的名字
var drs = new DrawRendererSettings(myCamera, new ShaderPassName("Opaque"));
// 开启instancing
drs.flag = DrawRendererFlags.EnableInstancing;
// 指定为渲染传递光照探针和光照贴图
drs.rendererConfiguration = RendererConfiguration.PerObjectLightProbe | RendererConfiguration.PerObjectLightmaps;
// 按照不透明物体的渲染顺序排序
drs.sorting.flags = SortFlags.CommonOpaque;
绘制 Drawing
现在,我们有三样数据要交给DrawCall:
- Cull Results 裁剪结果
- Filtering rules 过滤规则
- Drawing rules 绘制规则
现在,我们可以进行DrawCall了。通过SRP Context的接口进行调用。在SRP中,不需要单独渲染一个Mesh,而是调用接口一次渲染一批Mesh:
// 绘制所有的renderers
context.DrawRenderers(cullResults.visibleRenderers, ref drs, opaqueRange);
// 提交渲染
context.Submit();
这回将对象渲染到当前的Render Target,也可以使用Command Buffer来切换Render Target。
XR应用SRP (Virtual Reality)
要在SRP中应用VR,开启VR并在PlayerSettings中选择VR SDK。此外,可以通过SRP提供的XRGraphicsConfig类来配置VR。现在,XRGraphicsConfig提供了XRSettings接口,将会扩展以适配各种XRSDK子系统。
摄像机组件 Camera Components
Free Camera
Free Camera组件提供了简单的自由摄像机实现。将该组件添加到摄像机后,可以使用键盘,鼠标,或手柄,在运行时控制位置和朝向。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jDrw8Qho-1581473895127)(https://docs.unity3d.com/Packages/com.unity.render-pipelines.core@7.1/manual/Images/FreeCamera1.png)]
属性:
- Look Speed Controller 用手柄控制摄像机旋转的速度
- Look Speed Mouse 用鼠标控制摄像机旋转的速度
- Move Speed 摄像机移动速度
- Move Speed Increment 修改摄像机移动速度时的增量。当场景太大,当前的移动速度无法很快的遍历场景时有用。自动加速???
- Turbo 当按下”Fire1“按键时,移动速度会乘上该值
Camera Switcher
Camera Switcher 允许定义一个摄像机列表,并能在Debug运行时,进行切换。当需要设置不同的视角来进行剖析,而且可以方便的切换对比,而保证位置不变。
属性:
- Cameras 将挂有Camera组件的Game Object拖动来添加摄像机到列表中。Debug Window可以在这些摄像机列表中进行切换。
最后
以上就是迷人帆布鞋为你收集整理的Unity 可编程渲染管线可编程渲染管线 Scriptable Render PipelineSRP入门 Getting Started用SRP渲染 Rendering with SRPXR应用SRP (Virtual Reality)摄像机组件 Camera Components的全部内容,希望文章能够帮你解决Unity 可编程渲染管线可编程渲染管线 Scriptable Render PipelineSRP入门 Getting Started用SRP渲染 Rendering with SRPXR应用SRP (Virtual Reality)摄像机组件 Camera Components所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复