【Unity Shader学习笔记】Unity光照-渲染路径

官方文档:渲染路径

1、简介

需要为每个 Shader 设置正确的渲染路径。

大多数情况下,一个项目只使用一种渲染路径,因此我们可以为整个项目设置渲染时的渲染路径。

Edit -> Project Settings -> Player -> Other Settings -> Rendering Path

默认为前向渲染路径。

也可以对不同摄像机设置不同渲染路径,以覆盖Project Setting中的设置。

2、种类

渲染路径的种类如下所示:

种类 简介
UseGraphicsSettings(UsePlayerSettings) 选择此选项意味着使用Project Setting中的设置
VertexLit 顶点照明渲染路径(旧,仅为兼容存在)
Forward Forward Rendering.
DeferredLighting 延迟渲染路径(旧,适用于固定管线,仅为兼容存在)
DeferredShading 延迟渲染路径(与相机正交投影不兼容)

3、Pass 中的 LightMode 标签

image-20220707163943865

4、前向渲染路径

4.1、原理

每次前向渲染,都需要对每个图元(fragment)执行一系列操作:先利用深度缓冲区判断这一像素是否可见,如果可见就计算其颜色值。

如果一个物体在我个光源的影响区域内,那么物体就要进行多次运算,理论上有多少光源就有多少Pass需要运算。

因此,引擎通常会限制每个逐像素光照的数目以减少需要的Pass。

4.2、Unity的前向渲染

Unity 中,前向渲染路径有三种处理光照的方式:逐顶点处理、逐像素处理、球谐函数处理(Spherical Harmonics, SH)。

在 Unity 中,我们可以设置一个光源是否是Important的。Unity 会优先将其作逐像素处理。

image-20220707175424463

前向渲染中,Unity会根据场景中各个光源的位置以及重要性将各个光源进行重要度排序。

一定数目的光源会按逐像素的方式处理,然后最多有 4 个光源按逐顶点的方式处理, 剩下的光源可以按 SH 方式处理。

Unity 使用的判断规则如下:

  • 场景中最亮的平行光总是按逐像素处理的。

  • 渲染模式被设置成 Not Important 的光源, 会按逐顶点或者 SH 处理。

  • 渲染模式被设置成 Important 的光源, 会按逐像素处理。

  • 如果根据以上规则得到的逐像素光源数量小于 Quality Setting 中的逐像素光源数量(Pixel Light Count),会有更多的光源以逐像素的方式进行渲染。

4.3、前向渲染种类

前向渲染有两种 Pass : Base Pass 和 Additional Pass。

image-20220707181819075
  • 可以发现在渲染设置中, 我们除了设置了 Pass 的标签外, 还使用了#pragma compile_fwdbase这样的编译指令。只有分别为 Bass Pass 和 Additional Pass 使用这两个编译指令, 我们才可以在相关的 Pass 中得到一些正确的光照变量, 例如光照衰减值等。
  • Base Pass 旁边的注释给出了 Base Pass 中支持的一些光照特性。 例如在 Base Pass 中, 我们可以访问光照纹理 (lightmap)。
  • Base Pass 中渲染的平行光默认是支持阴影的( 如果开启了光源的阴影功能), 而 Additional Pass 中渲染的光源在默认情况下是没有阴影效果的, 即便我们在它的 Light 组件中设置了有阴影的 Shadow Type。 但我们可以在 Additional Pass 中使用#pragma multi compile fwdadd fullshadows代替#pragma multi compile fwdadd编译指令, 为点光源和聚光灯开启阴影效果, 但这需要 Unity 在内部使用更多的 Shader 变种。
  • 环境光和自发光也是在 Base Pass 中计算的„ 这是因为, 对于物体来说, 环境光和自发光我们只希望计算一次即可, 而如果我们在 Additional Pass 中计算这两种光照, 就会造成叠加多次环境光和自发光。
  • 在 Additional Pass 的渲染设置中, 我们还开启和设置了混合模式。 这是因为, 我们希望每个 Additional Pass 可以与上一次的光照结果在帧缓存中进行叠加, 从而得到最终的有多个光照的渲染效果。通常情况下, 我们选择的混合模式是 Blend One One
  • 对于前向渲染来说, 一个 Unity Shader 通常会定义一个 Base Pass ( Base Pass 也可以定义多次, 例如需要双面渲染等情况) 以及一个 Additional Pass。 一个 Base Pass 仅会执行一次( 定义了多个 Base Pass 的情况除外), 而一个 Additional Pass 会根据影响该物体的其他逐像素光源的数目被多次调用, 即每个逐像素光源会执行一次 Additional Pass。

上述光照计算是通常情况下我们在每种 Pass 中进行的计算,即逐像素计算。
当然也可以Base Pass 与 Additional Pass 中只进行逐顶点光照。

如果场景中有多个平行光,Unity 会选择最亮的平行光传递给 Base Pass 进行逐像素处理。
其他平行光会按照逐顶点或在 Additional Pass 中按逐像素的方式处理。
如果场景中没有任何平行光, 那么 Base Pass 会当成全黑的光源处理。

4.4、前向渲染变量

对于前向渣染( 即 LightMode 为 ForwardBase 或 FonvardAdd ) 来说下面是我们可以在 Shader 中访问到的光照变量。

image

前向渲染中可以使用的内置光照函数如下:

image

5、顶点照明渲染路径

即使用逐定点的方式渲染。这种方法速度最快,但是效果最差,且无法支持阴影、法线映射、高精度的高光反射等。

5.1、顶点照明渲染

在这个 Pass 中, 我们会计算我们关心的所有光源对该物体的照明, 并且这个计算是按逐顶点处理的。

这是 Unity 中最快速的渲染路径, 并且具有最广泛的硬件支持。

游戏机上并不支持这种路径

其实,顶点照明渲染路径仅仅是前向渲染路径的一个子集,目前仅作为遗留的渲染路径。

5.2、可访问的内置变量与函数

在 Unity 中, 我们可以在一个顶点照明的 Pass 中最多访问到 8 个逐顶点光源。 如果我们只需要渲染其中两个光源对物体的照明, 可以仅使用表 9.4 中内置光照数据的前两个。 如果影响该物体的光源数目小于 8, 那么数组中剩下的光源颜色会设置成黑色。

image

image

6、延迟渲染路径

官方文档:https://docs.unity3d.com/Manual/RenderTech-DeferredShading.html

6.1、延迟渲染的原理

延迟渲染包含两个Pass。

  • 第一个Pass中,使用深度缓冲技术计算那些片元是可见的,如果可见,就把它的相关信息存储到G缓冲区(Geometry-buffer)中。

第一个Pass只会执行一次。

  • 第二个Pass中,利用G缓冲区的各个信息进行光照计算。

因此,延迟渲染的效率不依赖于场景光源的数量,而是与屏幕像素数量有关。

6.2、Unity 中的延迟渲染

两种延迟渲染:

  • 遗留的延迟渲染:旧版延迟渲染,不支持 Unity 的基于物理的Standard Shader。
  • 延迟渲染:适合在光源数量多的情况下进行,而且每个光源都可以按照逐像素的方式处理。

但是,延迟渲染也有一些缺点:

  • 不支持真正的抗锯齿功能(但是现在有新的技术解决这一问题)

  • 不能处理半透明物体

  • 要求显卡支持 MRT (Multiple Render Targets,多目标渲染)、Shdaer Mode 3.0 及以上,深度渲染纹理以及双面的模板缓冲。从 GeForce 8xxx、Radeon X2400、Intel G45 开始,显卡均支持此功能。在移动设备上,所有至少运行 OpenGL ES 3.0 的设备都支持延迟着色。

注意:使用正交投影时不支持延迟渲染。如果相机的投影模式设置为正交,相机回退到前向渲染。

默认的G缓冲区包含以下渲染纹理(Render Texture, RT):

  • RT0,格式是ARGB32:
    漫反射颜色 (RGB通道)、遮挡 (A通道)。
  • RT1,格式是ARGB32:
    高光反射颜色(RGB通道)、平滑度/高光反射的指数部分 (A通道)。
  • RT2,格式是ARGB2101010:
    世界坐标下法线 (RGB),未使用 (A)。
  • RT3,格式是ARGB2101010(非 HDR)或 ARGBHalf (HDR):
    自发光 + lightmap + 反射探针( reflection probes)。
  • 深度缓冲+模板缓冲

the default G-buffer layout is 160 bits/pixel (non-HDR) or 192 bits/pixel (HDR).

如果对混合光照使用ShadowmaskDistance Shadowmask模式,则使用第五个目标:

  • RT4,格式是ARGB32 :光遮挡值/ Light occlusion values (RGBA)。

当在第二个 Pass 中计算光照时, 默认情况下仅可以使用 Unity 内置的 Standard 光照模型。 如果我们想要使用其他的光照模型, 就需要替换掉原有的 Imemal-DeferredShading.Shader 文件。

Unity 官方文档中解释如下:
The only lighting model available is Standard.
If a different model is wanted you can modify the lighting pass shader, by placing the modified version of the Internal-DeferredShading.shader file from the Built-in shaders into a folder named “Resources” in your “Assets” folder.
Then open the Graphics settings (menu: Edit > Project Settings, then click the Graphics category).
Change the “Deferred” dropdown to “Custom Shader”.
Then change the Shader option which appears to the shader you are using.

6.3、可访问内置变量与函数

这些变量都可以在 UnityDeferredLibrary.cginc 文件中找到它们的声明。

image

7、总结

官方文档:https://docs.unity3d.com/Manual/RenderingPaths.html

Features Deferred Forward Legacy Deferred Vertex Lit
Per-pixel lighting (normal maps, light cookies) Yes Yes Yes -
Real-time shadows Yes With caveats Yes -
Reflection Probes Yes Yes - -
Depth & Normal Buffers Yes Additional render passes Yes -
Soft Particles Yes - Yes -
Semi-transparent objects - Yes - Yes
Anti-Aliasing - Yes - Yes
Light Culling Masks Limited Yes Limited Yes
Lighting Fidelity All per-pixel Some per-pixel All per-pixel All per-vertex
Performance
Cost of a per-pixel Light Number of pixels it illuminates Number of pixels * Number of objects it illuminates Number of pixels it illuminates -
Number of times objects are normally rendered 1 Number of per-pixel lights 2 1
Overhead for simple Scenes High None Medium None
Platform Support
PC (Windows/Mac) Shader Model 3.0+ & MRT All Shader Model 3.0+ All
Mobile (iOS/Android) OpenGL ES 3.0 & MRT, Metal (on devices with A8 or later SoC) All OpenGL ES 2.0 All
Consoles XB1, PS4 All XB1, PS4, 360 -
posted @ 2022-07-18 09:29  IDEA_W  阅读(455)  评论(1编辑  收藏  举报