Unity-TA 成长之路(二)内置渲染管线-官方篇

本篇为Unity官方文档的摘抄集合,为方便后续翻看。

1、渲染路径

        Unity 的内置渲染管线支持不同渲染路径。渲染路径是与光照和阴影相关的一系列操作。不同的渲染路径具有不同功能和性能特征。应根据项目类型以及目标硬件,选择渲染路径。

        可在 Graphics 窗口中选择项目使用的渲染路径,并可为每个摄像机覆盖该路径。

        如果运行项目的设备上的 GPU 不支持所选的渲染路径,则 Unity 将自动使用较低保真度的渲染路径。例如,在无法处理延迟着色的 GPU 上,Unity 使用前向渲染。

1.1 前向渲染

        前向渲染是内置渲染管线中的默认渲染路径。这是通用的渲染路径。

1.1.1 简介

        采用前向渲染方式渲染实时光源会非常消耗资源。为了抵消此成本,可以选择 Unity 在任何一个时间应该为每个像素渲染的光源数量。Unity 会以较低保真度渲染场景中的其余光源:每个顶点或每个对象。

        如果项目没有使用大量实时光源,或者光照保真度对项目而言不重要,则此渲染路径可能是这个项目的不错选择。

        前向渲染根据影响对象的光源在一个或多个通道中渲染每个对象。光源本身也可以通过前向渲染进行不同的处理,具体取决于它们的设置和强度。

1.1.2 实现详细信息

        在前向渲染中,影响每个对象的一些最亮的光源以完全逐像素光照模式渲染。然后,最多 4 个点光源采用每顶点计算方式。其他光源以球谐函数 (SH) 计算,这种计算方式会快得多,但仅得到近似值。

光源是否为每像素光源根据以下原则而定:

  • Render Mode 设置为 Not Important 的光源始终为每顶点或 SH 光源。
  • 最亮的方向光始终为每像素光源。
  • Render Mode 设置为 Important 的光源始终为每像素光源。
  • 如果上述情况导致光源数少于当前的 Pixel Light Count 质量设置,则按照亮度降低的顺序,更多光源采用每像素渲染方式。

每个对象的渲染按如下方式进行:

  • 基础通道应用一个每像素方向光和所有每顶点/SH 光源。
  • 其他每像素光源在额外的通道中渲染(每个光源对应一个通道)。

例如,如果某个对象受到许多光源的影响(下图中的圆形受光源 A 到 H 的影响):

        让我们假设光源 A 到 H 具有相同的颜色和强度,并且所有光源都具有自动渲染模式,因此它们将严格按照此对象的以下顺序排序。最亮的光源将以每像素光照模式渲染(A 到 D),然后最多 4 个光源以每顶点光照模式渲染(D 到 G),最后其余光源以 SH 进行渲染(G 到 H):

        光源组会重叠,例如,最后一个每像素光源混合到每顶点光照模式,因此当对象和光源移动时,“光射量”(light popping) 较少。

1.1.3 基础通道

        基础通道使用一个每像素方向光和所有 SH/每顶点光源来渲染对象。此通道还会添加着色器中的所有光照贴图、环境光照和发射光照。在此通道中渲染的方向光可以具有阴影。请注意,光照贴图的对象不会从 SH 光源获得光照。

         在着色器中使用“OnlyDirectional”通道标志时,前向基础通道仅渲染主方向光、环境光/光照探针和光照贴图(SH 和顶点光源不包括在通道数据中)。

1.1.4 其他通道

        对于影响此对象的每个额外的每像素光源,需要额外的渲染通道。默认情况下,这些通道中的光源没有阴影(因此在结果中,前向渲染支持一个带阴影的方向光),除非使用 multi_compile_fwdadd_fullshadows 变体快捷方式。

1.1.5 性能注意事项

        球谐函数光源的渲染速度_很_快。这些光源的 CPU 成本很低,并且使用 GPU 的_成本基本为零_(也就是说,基础通道始终会计算 SH 光照;但由于 SH 光源工作方式的原因,无论 SH 光源有多少,成本都完全相同)。

SH 光源的缺点:

  • 按对象的顶点而不是按像素计算。这意味着它们不支持光照剪影和法线贴图。
  • SH 光照的频率很低。SH 光源无法实现快速的光照过渡。它们也只影响漫射光照(频率对镜面高光而言太低)。
  • SH 光照不是局部光照;SH 点光源或聚光灯在靠近某种表面时“看起是错误的”。

总的来说,SH 光源通常足以达到小型动态对象的光照要求。

1.2 延迟着色

1.2.1 简介

        延迟着色是内置渲染管线中具有最大光照和阴影保真度的渲染路径。  

        延迟着色需要 GPU 支持,并且有一些局限性。这种着色方式不支持半透明对象(Unity 使用前向渲染来渲染这些对象)、正交投影(Unity 对这些摄像机使用前向渲染)或硬件抗锯齿(但可以使用后期处理效果来获得类似结果)。延迟着色对剔除遮罩的支持有限,并会将 Renderer.receiveShadows 标志始终视为 true。

        如果项目具有大量的实时光源并需要高级别的光照保真度,而目标硬件支持延迟着色,那么此渲染路径对于该项目而言可能是一个不错的选择。

1.2.2 概述

        使用延迟着色时,可影响游戏对象的光源数量没有限制。所有光源都按像素进行评估,这意味着它们都能与法线贴图等正确交互。此外,所有光源都可以有剪影和阴影。

        延迟着色的优点是,光照的处理开销与接受光照的像素数成正比。这取决于场景中的光量大小,而不管接受光照的游戏对象有多少。因此,可通过减少光源数量来提高性能。延迟着色还具有高度一致和可预测的行为。每个光源的效果都是按像素计算的,因此不会有在大三角形上分解的光照计算。

        在缺点方面,延迟着色并不支持抗锯齿,也无法处理半透明游戏对象(这些对象使用前向渲染进行渲染)。此外,它也不支持网格渲染器 (Mesh Renderer) 的接受阴影 (Receive Shadows) 标志,并且仅在有限程度上支持剔除遮罩。最多只能使用四个剔除遮罩。也就是说,剔除层遮罩必须至少包含所有层减去四个任意层,即必须设置 32 个层中的 28 个层。否则,会产生图形瑕疵。        

1.2.3 要求     

        延迟着色要求显卡具有多渲染目标 (MRT)、着色器模型 3.0(或更高版本)并支持深度渲染纹理。从 GeForce 8xxx、Radeon X2400、Intel G45 开始,2006 年以后制造的大多数 PC 显卡都支持延迟着色。

        所有至少运行 OpenGL ES 3.0 的移动设备都支持延迟着色。

注意:使用正交投影 (Orthographic projection) 时不支持延迟渲染。如果摄像机的投影模式设置为正交模式,则摄像机将回退到前向渲染。

1.2.4 性能注意事项

        延迟着色中的实时光源的渲染开销与接受光照的像素数成比例,并_不_依赖于场景复杂度。所以小型点光源或聚光灯的渲染成本非常低,如果它们被场景游戏对象完全或部分遮挡,那么成本甚至更低。

        当然,有阴影的光源比没有阴影的光源的成本高得多。在延迟着色中,对于每个阴影投射光源,仍然需要将投射阴影的游戏对象渲染一次或多次。此外,应用阴影的光照着色器的渲染开销高于禁用阴影时的渲染开销。

1.2.5 实现详细信息

        如果对象的着色器不支持延迟着色,则会在延迟着色结束后使用前向渲染路径来渲染这些对象。

        下面列出了 G 缓冲区中渲染目标 (RT0 - RT4) 的默认布局。数据类型放置在每个渲染目标的各个通道中。使用的通道显示在括号内。

  • RT0,ARGB32 格式:漫射颜色 (RGB),遮挡 (A)。
  • RT1,ARGB32 格式:镜面反射颜色 (RGB),粗糙度 (A)。
  • RT2,ARGB2101010 格式:世界空间法线 (RGB),未使用 (A)。
  • RT3,ARGB2101010(非 HDR)或 ARGBHalf (HDR) 格式:发射 + 光照 + 光照贴图 + 反射探针缓冲区。
  • 深度+模板缓冲区。

        因此,默认的 G 缓冲区布局为 160 位/像素(非 HDR)或 192 位/像素 (HDR)。

        如果混合光照模式为 ShadowmaskDistance Shadowmask,则使用第五个目标:*RT4,ARGB32 格式:光照遮挡值 (RGBA)。

        因此,G 缓冲区布局为 192 位/像素(非 HDR)或 224 位/像素 (HDR)。

        如果硬件不支持五个并发渲染目标,则使用阴影遮罩的对象将回退到前向渲染路径。 当摄像机不使用 HDR 时,发射+光照缓冲区 (RT3) 采用对数编码,因此提供的动态范围高于 ARGB32 纹理通常可能提供的范围。

        当摄像机使用 HDR 渲染时,不会为发射 + 光照缓冲区 (RT3) 创建单独的渲染目标;而是将摄像机渲染到的渲染目标(即传递给图像效果的渲染目标)用作 RT3。        

1.2.6 G缓冲区通道

        G 缓冲区通道将每个游戏对象渲染一次。漫射和镜面反射颜色、表面平滑度、世界空间法线和发射+环境+反射+光照贴图都将渲染到 G 缓冲区纹理中。G 缓冲区纹理设置为全局着色器属性供着色器以后访问(_CameraGBufferTexture0 .._CameraGBufferTexture3 指定)。

1.2.7 光照通道    

        光照通道根据 G 缓冲区和深度来计算光照。光照是在屏幕空间内计算的,因此处理所需的时间与场景复杂性无关。光照将添加到发射缓冲区。

        不与摄像机近平面相交的点光源和聚光灯将渲染为 3D 形状,并会启用 Z 缓冲区对场景的测试。因此,部分或完全遮挡的点光源和聚光灯的渲染成本很低。方向光以及与近平面相交的点光源/聚光灯将渲染为全屏四边形。

        如果光源启用了阴影,那么也会在此通道中渲染并应用阴影。请注意,阴影并非是“无成本”的;需要渲染阴影投射物,并且必须应用更复杂的光照着色器。

        唯一可用的光照模型是标准 (Standard) 光照模型。如果需要不同的模型,可修改光照通道着色器,方法是将内置着色器中的 Internal-DeferredShading.shader 文件的修改版本放入“Assets”文件夹中名为“Resources”的文件夹内。然后打开 Graphics 设置(菜单:Edit > Project Settings,然后单击 Graphics 类别)。将“Deferred”下拉选单改为“Custom Shader”。然后,更改当前使用的着色器对应的着色器 (Shader) 选项。

 1.3 旧版延迟 (Legacy Deferred)

        旧版延迟(光照预通道)类似于延迟着色,只是采用不同的技术并进行不同的折中。它不支持 Unity 5 基于物理的标准着色器。

        从 Unity 5.0 开始,旧版延迟渲染路径被认为是旧版功能,因为它不支持某些渲染功能(例如标准着色器、反射探针)。新项目应考虑改用延迟着色渲染路径。使用正交投影 (Orthographic projection) 时不支持延迟渲染。如果摄像机的投影模式设置为正交模式,则摄像机将始终使用前向渲染。

1.3.1 概述

        使用延迟光照时,可影响对象的光源数量没有限制。所有光源都按像素进行评估,这意味着它们都能与法线贴图等正确交互。此外,所有光源都可以有剪影和阴影。

        延迟光照的优点是,光照的处理开销与接受光照的像素数成正比。这取决于场景中的光量大小,而不管接受光照的对象有多少。因此,可通过减少光源数量来提高性能。延迟光照还具有高度一致和可预测的行为。每个光源的效果都是按像素计算的,因此不会有在大三角形上分解的光照计算。

        在缺点方面,延迟光照并不支持抗锯齿,也无法处理半透明对象(这些对象将使用前向渲染进行渲染)。此外,它也不支持网格渲染器 (Mesh Renderer) 的接受阴影 (Receive Shadows) 标志,并且仅在有限程度上支持剔除遮罩。最多只能使用四个剔除遮罩。也就是说,剔除层遮罩必须至少包含所有层减去四个任意层,即必须设置 32 个层中的 28 个层。否则,将产生图形瑕疵。

1.3.2 要求

        延迟光照要求显卡具有着色器模型 3.0(或更高版本)、支持深度渲染纹理以及具有双面模板缓冲区。 2004 年以后制造的大多数 PC 显卡都支持延迟光照,包括 GeForce FX 及更高版本、Radeon X1300 及更高版本、 Intel 965/GMA X3100 及更高版本。在移动端,所有支持 OpenGL ES 3.0 的 GPU 都支持延迟光照,而一部分 支持 OpenGL ES 2.0 的 GPU 也支持延迟光照(即支持深度纹理的 GPU)。

1.3.3 性能注意事项

        延迟光照中的实时光源的渲染开销与接受光照的像素数成比例,并_不_依赖于场景复杂度。所以小型点光源或聚光灯的渲染成本非常低,如果它们被场景对象完全或部分遮挡,那么成本甚至更低。

        当然,有阴影的光源比没有阴影的光源的成本高得多。在延迟光照中,对于每个阴影投射光源,仍然需要将投射阴影的对象渲染一次或多次。此外,应用阴影的光照着色器的渲染开销高于禁用阴影时的渲染开销。

1.3.4 实现详细信息

        使用延迟光照时,Unity 中的渲染过程在三个通道中进行:

        (1)基础通道:渲染对象以生成具有深度、法线和镜面反射能力的屏幕空间缓冲区。

        (2)光照通道:将先前生成的缓冲区用于计算光照以进入另一个屏幕空间缓冲区。

        (3)最终通道:再次渲染对象。它们会获取计算出的光照,将其与颜色纹理相结合,并添加环境/发射光照。

        如果对象的着色器无法处理延迟光照,则会在此过程结束后使用前向渲染路径来渲染这些对象。

1.3.5 基础通道

        基础通道将每个对象渲染一次。视图空间法线和镜面反射能力将渲染到单个 ARGB32 渲染纹理中(法线位于 RGB 通道中,而镜面反射强度位于 A 通道中)。如果平台和硬件允许将 Z 缓冲区作为纹理读取,则不会显式渲染深度。如果无法将 Z 缓冲区作为纹理访问,则会使用着色器替换在另外的渲染通道中渲染深度。

        基础通道的结果是填充了场景内容的 Z 缓冲区以及包含法线和镜面反射能力的渲染纹理。

1.3.6 光照通道

        光照通道根据深度、法线和镜面反射能力来计算光照。光照是在屏幕空间内计算的,因此处理所需的时间与场景复杂性无关。光照缓冲区是单个 ARGB32 渲染纹理,其中在 RGB 通道中包含漫射光照,而在 A 通道中包含单色镜面光照。光照值采用对数编码,因此提供的动态范围高于 ARGB32 纹理通常可能提供的范围。如果摄像机启用了 HDR 渲染,则光照缓冲区为 ARGBHalf 格式,并且不执行对数编码。

        不与摄像机近平面相交的点光源和聚光灯将渲染为 3D 形状(的正面),并会启用对场景的深度测试。与近平面相交的光源也用 3D 形状进行渲染,但作为背面并进行反向深度测试。因此,部分或完全遮挡的光源的渲染成本很低。如果光源同时与摄像机的远平面和近平面相交,则不能使用上述优化,而光源会被绘制为紧密四边形并且不进行深度测试。

        以上说明不适用于方向光;方向光总是渲染为全屏四边形。

        如果光源启用了阴影,那么也会在此通道中渲染并应用阴影。请注意,阴影并非是“无成本”的;需要渲染阴影投射物,并且必须应用更复杂的光照着色器。

        唯一可用的光照模型是 Blinn-Phong。如果需要不同的模型,可修改光照通道着色器,方法是将内置着色器中的 Internal-PrePassLighting.shader 文件的修改版本放入“Assets”文件夹中名为“Resources”的文件夹内。然后,选择 Edit > Project Settings > Graphics 窗口。将“Legacy Deferred”下拉选单改为“Custom Shader”。然后,更改当前使用的光照着色器对应的着色器 (Shader) 选项。

1.3.7 最终通道

        最终通道将产生最终渲染的图像。在此阶段将再次使用着色器渲染所有对象,这些着色器会获取光照,将其与纹理相结合,并添加发射光照。在最终通道中还会应用光照贴图。在靠近摄像机的位置将使用实时光照,并且仅添加烘焙间接光照。因此会交叉淡入远离摄像机的完全烘焙光照。

1.4 旧版顶点光照

        旧版顶点光照 (Legacy Vertex Lit) 是具有最低光照保真度且不支持实时阴影的渲染路径。这是前向渲染路径的子集。

        顶点光照路径通常在一个通道中渲染每个对象,并为每个顶点计算所有光源的光照。

        顶点光照路径是最快的渲染路径,具有最广泛的硬件支持。

        由于所有光照都是在顶点级别计算的,因此该渲染路径不支持大多数每像素效果:阴影、法线贴图、光照剪影和高度细节化的镜面高光都不受支持。

1.5 渲染路径比较

延迟前向旧版延迟顶点光照
功能
每像素光照(法线贴图、光照剪影)-
实时阴影带有警告-
反射探针--
深度和法线缓冲区其他渲染pass-
软粒子--
半透明对象--
抗锯齿--
光照剔除遮罩受限受限
光照保真度全部每像素部分每像素全部每像素全部每顶点
性能
每像素光照的成本照射像素数量像素数量 * 照射对象数量照射像素数量-
正常渲染对象的次数1每像素光照的数量21
简单场景的开销
平台支持
PC (Windows/Mac)Shader Model 3.0+ 和 MRT所有Shader Model 3.0+所有
移动端 (iOS/Android)OpenGL ES 3.0 和 MRT、Metal(在搭载 A8 或更高版本 SoC 的设备上)所有OpenGL ES 2.0所有
游戏主机XB1、PS4所有XB1、PS4、360-

2、使用 CommandBuffer 来扩展内置渲染管线

        包含有关在内置渲染管线中使用 CommandBuffer 的信息。有关在渲染管线中基于可编程渲染管线使用 CommandBuffer 的信息,请参阅在可编程渲染管线中调度和执行渲染命令

2.1 CommandBuffer 基础知识

CommandBuffer  保存渲染命令列表(例如设置渲染目标或绘制给定网格)。可以指示 Unity 在内置渲染管线中的各个点安排和执行这些命令,因此,您可以自定义和扩展 Unity 的渲染功能。

使用 CommandBuffer 进行模糊折射
使用 CommandBuffer 进行模糊折射

        可以使用 Graphics.ExecuteCommandBuffer API 立即执行 CommandBuffer,也可以进行安排,让它们在渲染管线中的给定点执行。要安排它们,请使用 Camera.AddCommandBuffer API 与CameraEvent 枚举,以及 Light.AddCommandBuffer API 与 LightEvent 枚举。要查看 Unity 何时执行以这种方式安排的 CommandBuffer,请参阅 CameraEvent 和 LightEvent 的执行顺序

        有关可以使用 CommandBuffer 执行的命令的完整列表,请参阅 CommandBuffer API 文档。请注意,一些命令仅在某些硬件上受支持。例如,与光线追踪有关的命令仅在 DX12 中受支持。

2.2 Command Buffer 示例

标题使用 Command Buffers 贴花

        Unity 博客文章扩展 Unity 5 渲染管线:CommandBuffer 介绍了内置渲染管线中的 CommandBuffer,并包含示例项目和示例代码。它介绍如何使用 CommandBuffer 来实现几种不同的效果,并包含一个示例项目和示例代码。项目是为 Unity 的旧版本创建的,但原理相同。

2.3 CameraEvent 事件的执行顺序

        CameraEvents 执行顺序取决于项目使用的渲染路径

2.3.1 延迟渲染路径

2.3.2 前向渲染路径

2.4 LightEvent 执行顺序

在上面的“渲染阴影”阶段,对于每个投射阴影的光源,Unity 执行以下步骤:

3、内置渲染管线的硬件要求

3.1 摘要 (Summary)

Win/Mac/LinuxiOS/Android游戏主机
延迟光照SM3.0、GPU 支持-
前向渲染
顶点光照渲染-
实时阴影GPU 支持GPU 支持
图像效果
可编程着色器
固定函数着色器-

3.2 实时阴影

        实时阴影 (Realtime Shadows) 适用于大多数 PC、游戏主机和移动平台。在 Windows (Direct3D) 上,GPU 还需要支持阴影贴图功能;自 2003 年以后,大多数独立 GPU 都支持这些功能,而自 2007 年以后,大多数集成 GPU 也支持这些功能。从技术上讲,在 Direct3D 9 上,GPU 必须支持 D16/D24X8 或 DF16/DF24 纹理格式;在 OpenGL 上,必须支持 GL_ARB_depth_texture 扩展。

        移动端阴影 (iOS/Android) 要求具备 OpenGL ES 2.0 和 GL_OES_depth_texture 扩展或者 OpenGL ES 3.0。最需要注意的是,该扩展在基于 Tegra 3 和 Tegra 4 的 Android 设备上存在,因此阴影在这些设备上不起作用。

3.3 后期处理效果

        后期处理效果要求有渲染到纹理功能;此功能通常在本世纪以来制造的硬件产品上都是受支持的。

3.4 着色器

        可以编写可编程着色器或固定函数着色器。可编程着色器在所有平台上都受支持,默认为 Shader Model 2.0(桌面端)和 OpenGL ES 2.0(移动端)。如果想要更多功能,可定位更高版本的着色器模型。固定函数着色器在除游戏主机外的所有平台上都受支持。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

末零

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值