英文原文:https://thegamedev.guru/rendering/unity-srp-overview-scriptable-render-pipeline/


  我决定做一些研究并编写即将推出的实验性 Unity 功能:Scriptable Rendering Pipelines。 为什么? 因为它关乎你,它关乎我。 但不要惊慌。 或者至少,现在还没有。 也许甚至明年都不会,但它最终会改变你的工作方式。 你越准备好,你就会越好。

1.什么是SRP?

  Scriptable Render Pipeline (SRP) 是一种新的 Unity 系统和思维方式,它允许任何图形程序员开发自定义的渲染循环。 这意味着,您将能够调整、减少、扩展游戏创建帧的方式。 这将增加您优化游戏、创建自定义视觉效果、使您的系统更易于维护、修复直到现在无法修复的错误的潜力,但它的主要优势在于它可以让您更详细地了解图形的工作原理。 这个想法基本上与(传统)黑盒内置渲染器相反,Unity 垄断了所应用的渲染算法。

  该技术随 Unity 2018.1 Beta 一起提供。 不过要小心,它仍处于试验阶段,可能会保持这种状态一段时间。 它的主要支柱是与 C++ 引擎紧密绑定的 C# API。 API 很可能在功能开发过程中发生变化。 它背后的主要赌注是,您将对游戏将执行的渲染过程进行更细粒度的控制。

Unity 在其代码中提供了两个渲染管道:

  • LWRP:轻量级渲染管线
  • HDRP:高清渲染管线

为了理解 SRP,有必要了解典型的每相机渲染过程的整体情况:

  1. Culling
  2. Drawing
  3. Post-processing

如果您了解这些方面,请随时跳过下一部分。

1.1 剔除

  帧的渲染通常从剔除开始。 让我们从一个非正式但简单的定义开始,这将有助于我们暂时理解它。CullingCPU 过程包括获取可渲染对象并根据相机的可见性标准对其进行过滤,以生成要渲染的对象列表。

  可渲染对象基本上是带有渲染器组件(如 MeshRenderer)的游戏对象,过滤只是意味着它是否会包含在列表中。 但是请注意,真正的剔除过程也会将灯光添加到等式中,但我们将跳过这些。

  剔除很重要,因为它大大减少了 GPU 必须处理的数据量和指令量。 如果我们在洞穴中,渲染一架正在运行的飞机可能没有意义,因为我们看不到它(但它可能会,例如它在洞穴内投射阴影)。 剔除本身需要一些处理器时间,这是引擎在平衡 CPU/GPU 负载时必须注意的事实。

  传入的几何体/灯光 + 相机设置 + 剔除算法 = 要绘制的渲染器列表

1.2 渲染

  在我们确定应该显示哪些数据之后,我们就去做吧。 一个常见的过程可以总结为以下步骤:

  1. 清除(返回)缓冲区内容(CPU) 我们丢弃之前生成的缓冲区。 它通常是颜色和深度缓冲区,但它可能包括用于其他技术(例如延迟着色)的自定义缓冲区。
  2. 排序 (CPU) 对象根据渲染队列进行排序(例如,从前到后不透明,从后到前透明以进行正确混合)。排序 (CPU) 根据渲染队列对对象进行排序(例如,从前到后不透明, 并且从后到前透明以进行适当的混合)。
  3. 动态批处理 (CPU) 我们尝试将渲染器组合为一个对象,这样我们就可以节省绘制调用。 此优化是可选的。
  4. 命令(绘制调用)准备和调度(CPU) 对于每个渲染器,我们准备一个绘制命令及其几何数据:顶点、uv 坐标、顶点颜色、着色器参数(如变换矩阵(MVP)、纹理 ID 等)。 沿着其数据的指令被提交给 API,API 将与驱动程序一起将这些原始信息打包并正确格式化为适合 GPU 的数据结构。
  5. Render pipeline (GPU) 非常粗略的描述:GPU接收并处理命令; 然后 GPU 前端组装几何体,执行顶点着色器,光栅化器启动,片段着色器完成它们的工作,GPU 后端管理混合,渲染目标并将所有内容写入不同的缓冲区。
  6. 等待 GPU 完成并交换缓冲区
    根据 VSync 设置,它甚至可能等待更长的时间来执行前后缓冲区交换。

这是一个过度简化的典型渲染过程。


在 GPU 填充缓冲区(颜色、深度和可能的其他)之后,开发人员可能会选择应用进一步的图像增强功能。 它们包括将着色器应用于输入纹理(创建的缓冲区)以用校正后的图像覆盖它们。 下面列出了一些:

效果 描述 性能成本
Bloom 它突出了明亮的发光区域,在源周围营造出一种光环效果 中等的
景深 (DoF) 根据设置的参数模糊屏幕的某些部分 昂贵的
SS 抗锯齿 柔化由有限分辨率产生的像素颜色之间的突然过渡 轻到贵
色彩校正 根据定义的规则更改颜色的行为
SS 环境光遮蔽 添加接触阴影(它使对象之间的区域变暗) 中等的

请注意,性能成本实际上取决于平台,但作为一般规则,后期效果对于移动设备来说是令人望而却步的。

  它们昂贵的一个原因是每个生成的片段通常需要从帧缓冲区(在集成 GPU 的 RAM 中)进行多次读取,进行一些计算,然后覆盖缓冲区。 如果将此过程添加到多个后期效果中,由于生成的过度绘制,您最终会使用过多的内存带宽。

现在我们有了初步的了解,回到我们的 SRP 主题。 还在我这儿? 我们为什么要学习 SRP? 它将如何影响您?

2. 为什么选择 SRP?

  主要问题是 Unity 的内置渲染器是单一的、巨大的黑盒渲染管道,它考虑了每个用例。 让它如此通用需要付出很大的代价:

  • 很难优化。
  • 在不破坏当前项目的情况下很难改变。
  • 它应该保持与以前版本的兼容性。
  • 很难进行自定义渲染过程和微调项目。
  • 自定义渲染代码容易产生难以追踪的副作用。
  • 大工作室害怕受到限制。

  这就是我打赌 Unity 决定采用 SRP 的原因。 这是一个重大举措,因为您可以在资产商店中找到的大量软件包需要进行调整才能与 SRP(场景光强度、材质、着色器等)一起使用。

  SRP 的优点基本上与其缺点相反,还有其他一些额外的好处,例如可以使用即将推出的工具,例如用于图形着色器编程的 Shadergraph(最终使使用表面着色器变得罕见)。 在我看来,最大的优势之一是通过了解渲染的工作原理,您将获得大量的学习。


基本 SRP

  我基于 Unity 示例编写了一个简单的 SRP,以展示创建自定义渲染算法是多么容易(但没用?)。 它首先为一个可脚本对象编写代码,该对象将作为 Unity 在启动时实例化我们的 SRP 的工厂:

[CreateAssetMenu(menuName = "SRP/Create RubenPipeline")]
public class RubenPipelineAsset : RenderPipelineAsset
{[SerializeField] private Color _clearColor;protected override IRenderPipeline InternalCreatePipeline(){return new RubenPipelineImplementation(_clearColor);}
}


  我添加了一个虚拟的可选变量,它指示要使用的清晰颜色。 创建脚本对象实例后,您最终必须在图形设置中分配它,以便 Unity 可以将其用于上述任务。


创建 SRP 工厂代码后,现在我们进入真正的实现:

public class RubenPipelineImplementation : RenderPipeline
{private Color _clearColor;public RubenPipelineImplementation(Color clearColor){_clearColor = clearColor;}public override void Render(ScriptableRenderContext renderContext, Camera[] cameras){base.Render(renderContext, cameras);RenderPipeline.BeginFrameRendering(cameras);// You can sort the cameras however you want hereforeach (var camera in cameras){RenderPipeline.BeginCameraRendering(camera);renderContext.SetupCameraProperties(camera);// Clearvar cb = new CommandBuffer();cb.ClearRenderTarget(true, true, _clearColor);renderContext.ExecuteCommandBuffer(cb);// 1. CullCullResults cullResults;CullResults.Cull(camera, renderContext, out cullResults);// 2. Rendervar drawRendererSettings = new DrawRendererSettings(camera, new ShaderPassName("BasicPass"));var filterRenderersSettings = new FilterRenderersSettings(true);renderContext.DrawRenderers(cullResults.visibleRenderers, ref drawRendererSettings, filterRenderersSettings);renderContext.Submit();}}
}

  这个过程部分对应于我们之前描述的通用渲染算法。 第一个任务是触发一些事件,以便 Unity 和第三方插件可以在渲染期间注入自定义代码:BeginFrameRendering、BeginCameraRendering。 然后,为了让 Unity 辅助函数工作,我们通过 renderContext.SetupCameraProperties 设置一些用于绘图的相机属性(矩阵、FoV、透视/正交、剪切平面等)。 然后我们清除当前颜色和深度缓冲区内容,将初始颜色设置为可编写脚本对象中提供的颜色。 我们对当前相机进行剔除处理,获取要绘制的渲染器列表。 因此,我们继续使用默认设置绘制剔除结果,并在准备好所有指令后,将它们提交给 API + 驱动程序。

  在我们开始测试我们的新渲染循环之前还有一件事。 我们需要一个带有自定义着色器的自定义材质来渲染我们的几何体。 为此,我准备了一个可以使用它的简单无光照着色器。 除了通过 LightMode 通道命名我们的着色器通道之外,没有什么特别的。

Shader "Unlit/NewUnlitShader"
{Properties{_MainTex ("Texture", 2D) = "white" {}}SubShader{Tags { "RenderType"="Opaque" }Pass{Tags { "LightMode" = "BasicPass" }CGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"struct appdata{float4 vertex : POSITION;float2 uv : TEXCOORD0;};struct v2f{float2 uv : TEXCOORD0;float4 vertex : SV_POSITION;};sampler2D _MainTex;float4 _MainTex_ST;v2f vert (appdata v){v2f o;o.vertex = UnityObjectToClipPos(v.vertex);o.uv = TRANSFORM_TEX(v.uv, _MainTex);return o;}fixed4 frag (v2f i) : SV_Target{return tex2D(_MainTex, i.uv);}ENDCG}}
}

现在准备好尝试了吗? 是的!


我为此感到自豪吗? 不,但一步一步。 对于好奇的人:它在 API 方面看起来如何? 是在听我的吩咐吗? 让我们打电话给我们的#bff RenderDoc。


  所以它完成了我们的要求,忽略了 Unity 编辑器细节的绘制调用。 不多也不少。 你明白为什么 SRP 很棒了吗? 全权控制,全责,最大的责备潜力! 我之前并没有真正指出,但我们使用可脚本化的对象来进行 SRP 的事实确实很强大。 您可以自定义您提供的参数并在运行时更改它们。 我还没有尝试过,但我敢打赌,我们将能够实时更改管道,让我们可以随意调整它以适应不同的设备。

预定义的渲染管线

  Unity 带有两个预定义的可编写脚本的渲染管道,您可以使用它们而无需进一步复杂化。 事实上,建议您使用其中任何一个作为模板来个性化您自己的管道,因为创建和维护其中一个肯定很难,相信我。 让我们简要描述一下它们:

LWRP(轻量级渲染管线):

  • 针对中低端设备的特定渲染算法
  • 内置渲染器的剥离版本
  • 以缩放分辨率渲染游戏
  • UI 以原始分辨率呈现
  • 没有实时GI

  你可以在网上找到官方内置渲染器与 LWRP 的比较以及 LWRP 源代码,如果你有一些(实际上,很多)空闲时间,我建议你看看。 还要检查比较,因为每次他们改变主意时我都不会修改此博客条目。

  HDRP(高清渲染管线)针对高端设备(台式机、PS4/XBO)并提供开箱即用的更好质量,包括延迟着色、TAA、HDR、PPAA、SSR、SSS 等。 喝杯茶,享受一段轻松而又令人兴奋的源代码阅读时光。

性能

  很抱歉让您失望了,但是现在用一个经常变化的高度不稳定的 API 进行基准测试是不可行的。 我从人们对 HDRP 和 LWRP 与内置渲染器的基准测试中发现的结果不一致,几乎没有可比性。 我将在以后的文章中介绍这一点,但由于我在上面几节中提到的原因,预计它会变得更好。

总结

  我们已经看到了渲染是什么样子,为什么 Unity 决定实现如此大的功能来支持弃用当前系统,Unity 是如何做到的,以及从今天开始渲染的开箱即用的可能性。 你可能已经意识到这篇文章是多么的简单,但是写得更彻底会让大多数读者望而却步。

[Render] Unity SRP 概述:可编写脚本的渲染管道相关推荐

  1. unity绘制管道_【译文】unity可编程渲染管道#1——自定义管道

    前言 Scriptable Render Pipeline定制流水线控制渲染创建管道资产和实例.剔除,过滤,排序,渲染.保持记忆清洁.提供良好的编辑体验.这是涵盖Unity可编写脚本的渲染系列教程的第 ...

  2. unity双击打不开脚本_游戏对象和脚本 (创建一个时钟)

    该文章是一篇译文,附上原文链接 Game Objects and Scripts​catlikecoding.com 使用简单对象构建一个时钟 编写一个C#脚本 转动时钟的指针来显示时间 创建指针动画 ...

  3. unity ui 概述_通过此概述了解Unity 2D和Platformer基础知识

    unity ui 概述 If you're shopping around for a 2D game engine, you've undoubtedly come across Unity. Di ...

  4. unity 天空盒_Unity自定义可编程渲染管线(SRP)(二)——编写第一个自定义SRP

    一句话描述,我们可以把SRP分解成两个部分,分别是SRP Asset,SRP Instance. SRP Asset SRP Asset是一个Unity Asset文件,用来存储渲染管线的特定配置信息 ...

  5. C#开发Unity游戏教程之使用脚本变量

    C#开发Unity游戏教程之使用脚本变量 使用脚本变量 本章前面说了那么多关于变量的知识,那么在脚本中要如何编写关于变量的代码,有规章可循吗?答案是有的.本节会依次讲解变量的声明.初始化.赋值和运算. ...

  6. AngularJs中,如何在render完成之后,执行Js脚本

    AngularJs是Google开源的前端JS框架.使用AngularJs, 我们能够容易地.健壮的开发出类似于Gmail一样的单页Web应用.AngularJs这个新兴的MVC前端框架,具有以下特点 ...

  7. Unity URP shader 出现 SRP Batcher 为 not compatible时 渲染性能会下降 应该怎么处理 ?

    以下是Unity官网对SPR Batcher 加速渲染的介绍 https://blog.unity.com/technology/srp-batcher-speed-up-your-rendering ...

  8. Unity游戏文本自动化生成脚本工具-姜雪伟-专题视频课程

    Unity游戏文本自动化生成脚本工具-717人已学习 课程介绍         在游戏开发中,策划填写好配置表,程序拿到配置表后,根据配置表中的项,在代码中定义结构体,编写加载函数接口,获取数据接口, ...

  9. 11C 以太坊 ethereum hardhat : 编写脚本

    • 介绍 • 使用 Hardhat CLI 运行脚本 • 独立脚本:使用 Hardhat 作为库 • Hardhat参数 • hardhat Tutorials , hardhat 教程 • Cont ...

  10. arcgis python脚本实现从界面选择输入输出_arcgis python脚本实现从界面选择输入输出_ArcGIS Python编程案例(2)-使用ArcPy编写脚本......

    本章将涉及以下案例: 使用ArcGIS Python窗体 访问ArcPy 从脚本中执行工具 使用ArcGIS桌面软件帮助系统 使用变量存储数据 访问ArcPy中的模块 引言 地理处理任务往往是耗时且重 ...

最新文章

  1. 把接口调用打成jar包的类怎么写_直观讲解RPC调用和HTTP调用的区别
  2. 跟你聊得这么投缘,你却说自己不是人?!
  3. 【高德地图开发1】---简介
  4. Deep learning:十九(RBM简单理解)
  5. [0] Tornado Todo 开篇
  6. tornado 08 数据库-ORM-SQLAlchemy-表关系和简单登录注册
  7. 百旺智能编码_【百旺】票字版开票软件操作指南已为您备好,请查阅!
  8. freeradius mysql php,freeradius mysql的相关配置说明
  9. 【Pytorch神经网络理论篇】 13 深层卷积神经网络介绍+池化操作+深层卷积神经网络实战
  10. windows部署PHP开发的cms系统
  11. 骨干考核系统系统流程及整体规则
  12. html 时间控件滚动选择器,TimePicker
  13. 解决Wireshark抓包跟踪流后http的响应正文乱码
  14. TP-LINK路由器配置
  15. 主板常见故障的维修方法
  16. Introduction to Fabric.js/ Part 8 - Clipping with clipPaths(介绍Fabric.js第八部分-剪裁)
  17. 物体重心的特点是什么_物体的重心
  18. 史上最全HTML实体字符整理
  19. jre环境变量配置(jre环境变量配置)
  20. Hardware - Serial Peripheral Interface - BIOS

热门文章

  1. L. Leverage MDT
  2. JDK源码如何启动编译
  3. python排序算法——快速排序时间复杂度O(nlogn)
  4. Windows和Linux平台上实现Word转PDF
  5. python 坦克大战
  6. vivado 开发教程(一) 创建新硬件工程
  7. Qt编写Onvif搜索及云台控制工具
  8. LM算法+推导+C++代码实践
  9. caffe教程笔记《Solver》
  10. 罗永浩承认鸟巢发布会不成功,还说苹果把大家都带歪了,你怎么看?