文档1:渲染管线 - Unity 手册
1、渲染管线简介 Render Pipeline
渲染管线执行一系列操作来获取场景Scene的内容,并将这些内容显示在屏幕上,主要包括:剔除、渲染、后期处理。
将项目从一个渲染管线切换到另一个渲染管线可能很困难,因为不同的渲染管线使用不同的着色器输出,并且可能没有相同的特性。因此,必须要了解 Unity 提供的不同渲染管线,以便可以在开发早期为项目做出正确决定。
内置渲染管线(Built-in RP),Unity 的默认渲染管线,自定义选项有限。
通用渲染管线(URP),快速轻松自定义的可编程渲染管线,可在各种平台上创建优化的图形。
高清渲染管线(HDRP),可编程渲染管线,可在高端平台上创建出色的高保真图形。
可编程渲染管线(SRP),使用API来创建自定义渲染管线。
各种渲染管线的特性对比:Render pipeline feature comparison - Unity 手册。
1.1、获取并配置活动渲染管线
活动渲染管线就是当前使用的渲染管线。要么使用内置渲染管线,要么使用基于SRP的渲染管线(URP、HDRP)。通过使用渲染管线资源(Render Pipeline Assets)来明确使用的SRP类型,否则将默认使用内置渲染管线。
对同一个渲染管线可以创建多个不同配置的渲染管线资源,例如对于不同的硬件条件。渲染管线资源的介绍在:SRP资源、URP资源、HDRP资源。
改变活动渲染管线时,需要确保现有的资源和代码与新的渲染管线兼容,否则有可能出错。
1.2、确定活动渲染管线
在菜单Edit -> Project Settings -> Graphics中的“Scriptable Render Pipeline Settings”属性来获取或设定默认渲染管线。在菜单Edit -> Project Settings -> Quality中的“Render Pipeline”属性来获取或设定渲染管线以重写默认的质量等级。
活动渲染管线的确定:① 若当前Quality中的质量等级 > “Render Pipeline”属性引用的渲染管线资源,则使用该值;② 若Graphics的设置 > “Scriptable Render Pipeline Settings”属性引用的渲染管线资源,则使用该值;③ 否则使用内置渲染管线。
1.3、设定活动渲染管线
激活内置渲染管线:取消Graphics和Quality中的所有渲染管线资源:① 在Graphics设置中,取消将渲染管线资源分配给渲染管线;② 在Quality设置中,对每个质量等级,取消将渲染管线资源分配给渲染管线。
激活URP/HDRP/SRP:为默认的活动渲染管线指定渲染管线资源,也可以为每个质量等级指定渲染管线资源:① 在Project文件夹中定位需要的渲染管线资源;② 设定默认的渲染管线,将渲染管线资源拖进Graphics的 “Scriptable Render Pipeline Settings”属性中;③ 为不同的质量等级设定重写的渲染管线资源,将将渲染管线资源拖进Quality的“Render Pipeline”属性中。
在C#脚本中获取/设定活动渲染管线:可以通过C#脚本来获取/设定活动渲染管线,并在其改变时获得反馈。How to get, set, and configure the active render pipeline - Unity 手册
(一)获取活动渲染管线:① 使用API GraphicsSettings.currentRenderPipeline 来获取定义活动渲染管线的渲染管线资源的引用。② 使用API GraphicsSettings.defaultRenderPipeline 来获取定义活动渲染管线的渲染管线资源的引用,API QualitySettings.renderPipeline 决定使用默认值或重写值。③ 使用API RenderPipelineManager.currentPipeline 来获取活动渲染管线的实例,Unity仅在用活动渲染管线渲染至少一帧后更新其属性。
(二)设定活动渲染管线:通过API GraphicsSettings.defaultRenderPipeline 和QualitySettings.renderPipeline 来设定活动渲染管线的值。
(三)监测活动管线管线:使用API RenderPipelineManager. activeRenderPipelineTypeChanged 来监测活动渲染管线类型的改变并执行代码。
2、配置光照渲染管线
官方最佳实践:选择和配置渲染管线和光照解决方案 - Unity 手册
2.1、渲染的基本概念
剔除:剔除摄像机视锥体不可见的对象,以及被遮挡的对象,列出需要渲染的对象。
渲染:将选择的对象绘制到基于像素的缓冲区中。
后期处理:在缓冲区上进行后期处理,例如应用颜色分级、泛光和景深,生成发送到显示器的最终输出帧。
着色器:在GPU上运行的程序、程序集的通用名。例如,在剔除阶段后,顶点着色器将渲染对象的点坐标从“对象空间”转换为“裁剪空间”,然后GPU将新的场景光栅化(将场景的矢量转换为实际像素)。像素着色器用于对这些像素进行着色,像素颜色取决于对象的表面材质、光照。
直接光照:从自发光光源直接发出的光照,非反射光,并且根据光源大小、与光源的距离,可以产生各种清晰的阴影。与方向光不同的是,方向光是模拟太阳发出的平行光,可以平行覆盖整个场景,不存在距离衰减。(实际上太阳光也是距离衰减的,但在小距离尺度上差异不大。)
间接光照:光从表面反射并通过介质的传播、散射,产生柔和、模糊的阴影。
全局光照/GI:对直接光照、间接光照进行建模以提供逼真的光照效果。GI分为:烘焙/动态光照贴图、辐照度体积、光传播体积、烘焙/光照探针、基于体素的GI、基于距离场的GI。
光照贴图:通过发射光线、计算光线反弹并将光线应用于纹理来生成光照贴图和光照探针。
2.2、光照管线梗概
如何点亮一个项目?
渲染管线 | 选择一个渲染管线 | 内置渲染管线、URP、HDRP、SRP |
光源设置 | 选择一个GI模式 | 烘焙GI、实时GI、烘焙&实时GI、None |
选择一个光源模式 | 直接烘焙、subtractive、阴影遮罩、距离阴影遮罩 | |
光源 | 添加光源 | 烘焙、实时、混合 |
添加发射面 | 烘焙GI、实时GI、None | |
添加反射探针 | 烘焙、实时、自定义 |
如何选择一个渲染管线?
3、内置渲染管线
Unity 的内置渲染管线是 比较陈旧的渲染管线,并非基于可编程渲染管线。可以通过选择不同的渲染路径来配置,使用CommandBuffer、反馈来拓展功能。
3.1、图形层 Graphics Tier
在内置渲染管线中,当应用运行在具有不同兼容性的硬件上时,可以使用图形层来应用不同的图片设置。可以在内置的层设置中来配置,或者在着色器/C#编码中自定义行为。(该功能只适用于内置渲染管线,其他渲染管线会检测硬件来获取Graphics.activeTier的值,但是无效。)
当第一次加载应用时,将检测硬件、图形API来决定当前的运行环境对应的图形层。不同的图形层及对应值如下:
值 | 硬件 | 图形层枚举值 | 着色器关键字 |
1 | Android(仅支持OpenGL ES 2)、IOS(5S之前)、iPads(第四代之前)、Desktop(DirectX9)、XR(HoloLens) | Tier1 | UNITY_HARDWARE_TIER1 |
2 | Android(支持OpenGL ES 3、Vulkan)、IOS(5S之后)、iPad Air、Apple TV、WebGL(全部) | Tier2 | UNITY_HARDWARE_TIER2 |
3 | Desktop(OpenGL、Metal、Vulkan、DirectX11+) | Tire3 | UNITY_HARDWARE_TIER3 |
C#脚本使用图形层:当前的图形层值存储在Graphics.activeTier中,可以直接进行设置。(必须在加载图形层的着色器之前进行,因此需要在预加载场景中设置。)
层设置:通过配置层设置启用/禁用每一层的图形特性,可以为某个目标的每一个图形层配置不同的层设置。在Graphics窗口中的Tier Setting中配置,或在,脚本中使用API Editor Graphics Settings或TierSettings。图形层设置通过修改内部着色器中的#define预处理指令生效,自动影响内置渲染管线中的预置着色器以及Surface Shader中的着色器库。
层的着色器变体:Unity对不同的图形层生成对应的着色器,通过在图层着色器中添加着色器关键字来生成层着色器变体。层着色器变体工作方式与一般着色器变体不同,Unity只加载活动图形层的着色器变体进CPU内存,这可以减少运行时间。在着色器的HLSL代码中,使用层着色器关键字可以为不同的硬件添加条件行为,例如,
#if UNITY_HARDWARE_TIER1
do ...
#else
do ...
3.2、渲染路径
渲染路径是与光照、阴影相关的一系列操作,不同的渲染路径右不同的功能、特性。在 Graphics 窗口中选择项目使用的渲染路径,并可为每个摄像机覆盖该路径。渲染路径分为:前向渲染、延迟着色、旧版延迟、顶点光照。
前向渲染:影响对象的最亮光源以完全逐像素模式渲染,后最多4各光源以逐顶点模式渲染,其他剩余光源以球谐函数SH渲染。(逐像素模式光源的要求:① 渲染模式设为Important;② 最亮方向的光;③ 若满足①②的光源数量小于Quality Setting中设置的像素光源数Pixel Light Count,按亮度降序排序,进行逐像素渲染。)基础通道使用一个逐像素方向光和所有 SH/逐顶点光源来渲染对象,还会添加着色器中的所有光照贴图、环境光照和发射光照(光照贴图的对象不会从SH光源获取光照,当着色器中使用“OnlyDirectional”通道标志时,前向基础通道仅渲染主方向光、环境光/光照探针和光照贴图(SH 和顶点光源不包括在通道数据中))。额外通道对基础通道外的其他逐像素光源进行渲染,这些光源没有阴影。逐像素光源的优化:避免多个光源照射单个对象。
延迟着色:可影响游戏对象的光源数量没有限制,且所有光源按逐像素模式评估,所有的光源都有阴影、剪影。因此,光照的处理开销与接受光照的像素数量成正比,即取决于光照数量,与被光照的游戏对象数量无关。可以通过减少光源数量来提高性能。但是,不支持抗锯齿、无法处理透明对象、不支持网格渲染器的接收阴影标识,最多支持4个剔除遮罩。延迟着色的优化:对于有阴影投射的光源,延迟着色仍需要将投射阴影的游戏对象渲染一次或多次,因此可以减少有阴影的光源、禁用光源的阴影。G缓冲区通道:将每个游戏对象渲染一次,漫射和镜面反射颜色、表面平滑度、世界空间法线和发射+环境+反射+光照贴图都将渲染到 G 缓冲区纹理中。G 缓冲区纹理设置为全局着色器属性供着色器以后访问。光照通道:光照通道根据 G 缓冲区和景深来计算光照。光照是在屏幕空间内计算的,因此处理所需的时间与场景复杂性无关。不与摄影机的近平面相交的点光源和聚光灯光源将渲染为3D形状,并启用Z缓冲区对场景的测试。这使得部分或完全遮挡的点光源和聚光灯光源的渲染成本非常低。穿过近平面的平行光和点光源或聚光灯渲染为全屏四边形。如果要渲染阴影投射,将应用更加复杂的光照着色器。
旧版延迟:与延迟着色类似。最终通道:生成最终的渲染图片。所有对象都使用着色器再次渲染,这些着色器获取光照,将其与纹理组合,并添加任何发射照明。最终通道中也使用光照贴图,接近摄像机的地方使用实时光照,远离摄像机的地方使用烘焙光照。
顶点光照:在一个通道中渲染每个对象,并为每个顶点计算所有光源的光照。顶点光照路径是最快的渲染路径,具有最广泛的硬件支持。顶点光照不支持大多数逐像素效果:阴影、法线贴图、光照剪影和高度细节化的镜面高光。
3.3、CommandBuffer拓展渲染管线
CommandBuffer是UnityEngine.Rendering中的类,是一个要执行的图形命令的列表。命令缓冲区保存渲染命令,可将渲染命令设置为在摄像机渲染(Camera.AddCommandBuffer)、光源渲染(Light.AddCommandBuffer)期间的各个点执行,或立即执行。
3.4、硬件需求
Win/Mac/Linux | iOS/Android | 游戏主机 | |
延迟光照 | SM3.0、GPU 支持 | - | 是 |
前向渲染 | 是 | 是 | 是 |
顶点光照渲染 | 是 | 是 | - |
实时阴影 | GPU 支持 | GPU 支持 | 是 |
图像效果 | 是 | 是 | 是 |
可编程着色器 | 是 | 是 | 是 |
固定函数着色器 | 是 | 是 | - |
实时阴影 (Realtime Shadows) 适用于大多数 PC、游戏主机和移动平台。在 Windows (Direct3D) 上,GPU 还需要支持阴影贴图功能。
后期处理效果要求有渲染到纹理功能,市场上的几乎所有硬件都支持。
可编程着色器在所有平台上都受支持,默认为 Shader Model 2.0(桌面端)和 OpenGL ES 2.0(移动端)。固定函数着色器在除游戏主机外的所有平台上都受支持。
3.5、自定义着色器编写相关的基本概念
创建着色器:菜单栏Create -> Shader -> Unlit Shader。仅显示一个纹理,无任何光照。
链接材质和着色器:在材质的Inspector中的Shader属性选择着色器,或者,在Project中将着色器拖到材质资源上。
链接对象和材质:将材质拖到Scene或Hierarchy中的游戏对象上,或者,在游戏对象的Inspector中的Mesh Renderer组件中选择材质。
着色器的代码实例:自定义顶点/像素着色器
Shader "Unlit/ShaderName" // 字符串代表着色器的名称
{
Properties {} // 着色器变量(纹理、颜色等),保存为材质的一部分
SubShader { // 子着色器用于实现不同GPU功能,可包含一个或多个
Tags {}
Pass { // 通道代表使用着色器材质渲染的同一对象执行顶点和代码块
CGPROGRAM // 包含顶点、像素着色器的HLSL代码部分
ENDCG
}
}
}
4、通用渲染管线 URP
官方文档:URP 12.1.7
通用渲染管线URP是由Unity预构建的可编程渲染管线SRP。URP 提供了对美术师友好的工作流程,可在移动平台、高端游戏主机和 PC 等各种平台上快速轻松地创建优化的图形。
4.1、兼容性要求
URP 12.0需要Unity 2021.2以上版本。使用URP制作的项目与HDRP、内置RP不兼容。URP包没有额外的平台专用需求。
封闭平台开发需要获取许可证。封闭平台的URP包无法在Package Manager中获取,需要从该平台相关的开发者论坛上下载,并使用Package Manager安装。
4.2、使用URP
在项目中使用URP,可以通过模板创建一个URP项目,或者,在一个使用内置RP的项目中导入URP(自己配置URP并手动修改某些项目内容)。目前版本的URP不支持自定义的后期效果,后续版本可支持。
通过模板创建一个URP项目:在创建项目页面选择URP模板,新建的项目将安装并配置URP(包含展示URP的例子)。
在已有项目中安装URP:URP使用集成的后期处理,若安装了 Post Processing Version 2包,需要将之删除后再安装URP。在Package Manager中安装URP(Universal RP)。在使用URP前需要进行配置:① 创建URP资源(包含项目的全局渲染、品质设置和渲染管线实例),在Project窗口中右击并选择Create -> Rendering -> URP Asset,或者,在菜单栏中选择Assets -> Create -> Rendering -> Universal Render Pipeline -> Pipeline Asset;② 将URP设为活动渲染管线,在菜单栏中选择Edit -> Project Setting -> Graphics,在Scriptable Render Pipeline Settings中选择URP资源的位置(在搜索栏中输入t:universalrenderpipelineasset来查找),或者,在菜单栏中选择Edit -> Project Setting -> Quality,选择一个品质等级,在Render Pipeline Asset中设置URP资源的位置。③ 更新着色器(内置RP的着色器与URP不兼容),使用将Render Pipeline Converter内置RP的着色器映射到URP的着色器,在菜单栏中选择Window -> Rendering -> Render Pipeline Converter,选择转换类型为Built-in to URP,勾选Material Upgrade来启用转换器,点击Initialize Converters预处理项目资源(可在列表中选择需要转换的元素),最后点击Convert Assets开始转化过程。
样例:URP有一系列的样例,从单个C#脚本到多个scene。在Package Manager中搜索Universal RP,在详情页找到Samples部分,导入需要的样例。样例安装在Assets/Samples/Universal RP/<package version>/。URP包样例包括:相机堆栈(将多个相机的输出分层堆成一个输出)、渲染器特性(可作为渲染器额外通道的资源)、镜头光斑、贴纸(在对象上添加投影其他材质)、着色器。
Scene模板:使用Scene模板快速创建包含预配置的UEP设定和后期处理的Scene。适用于URP的模板有:① Basic(URP),包含一个摄像机和一个光源,是默认scene的URP等价形式;② Standard(URP),包含一个摄像机、一个光源、一个带多种后期效果的全局体积Volumes。
4.3、渲染管线概念
URP资源:使用URP需要创建URP资源,并分配给Graphics Settings。URP资源控制URP的某些图形特性和品质设定。当在Graphics Settings中分配资源时,Unity将从内置RP切换成URP。测试不同效果不需要手动切换配置,只需要切换URP资源。
URP可配置的设定:Rendering(管线渲染框架的核心)、Quality(URP的品质等级,在不同水平的硬件上平衡性能和品质)、Lighting(设置光源,可禁用某些设置以缩短渲染时间)、Shadows(控制阴影的外观、渲染性能)、Post-processing(微调全局后期效果设定)、Adaptive Performance(启用Adaptive Performance功能,实时调整渲染品质)。
URP全局设定 Global Settings:安装URP后,将在Project Settings -> Graphics中出现URP Global Settings。包含以下属性:Light Layer Names(3D)(仅用于3D渲染器的光源层名称)、Shader Stripping(在构建Player时剥离的着色器)。
通用渲染器:通用渲染器的渲染路径分为前向渲染、延迟渲染。在URP资源的Inspector页的Renderer List属性中可以找到通用渲染器资源Universal Renderer asset。
通用渲染器资源引用:Filtering(过滤,选择渲染器需要绘制的层)、Rendering(渲染,与渲染相关的性质,包括渲染路径、景深启动、精确G缓冲区法线、复制景深等)、Native RenderPass(是否使用URP的原生渲染通道)、Shadows(是否在透明对象上绘制阴影)、Overrides(展示重写的渲染器属性,处理Stencil缓存值)、Compatibility(后续的兼容性,控制URP是否使用过渡纹理渲染)。
URP的延迟渲染:在URP通用渲染器资源的Lighting -> Rendering Path中,将属性值设为Deferred(随后出现精确G缓冲区法线属性,控制G缓冲区中法线编码方式,开启时更精确但是成本高)。
G缓冲区布局:延迟渲染路径中G缓冲区存储材质属性的方式。
渲染器特性:渲染器特性是可以添加额外的渲染路径到URP渲染器,并进行配置的一组资源。URP内置的渲染器特性是渲染对象Render Objects。
添加渲染器特性:在Project种选中一个渲染器,在Inspector种点击Add Renderer Feature,选择需要的渲染器特性。添加后,Inspector中的渲染器特性下出现相关属性(Name、Event、Filters、Pass Name、Overrides),Project中的渲染器下出现子项。
4.4、渲染
URP渲染Scene使用:URP渲染器(通用渲染器、2D渲染器)、URP附带着色器的着色器模型、摄像机、URP资源。
URP通用渲染器的帧渲染循环:在渲染一帧的前后、渲染每个摄像机循环的前后,可以使用RenderPipelineManager类中的事件(beginCameraRendering、beginFrameRendering、endCameraRendering、endFrameRendering)处理代码,例见自定义URP。
当渲染管线在Graphics Settings中激活时,将使用URP选择项目中的所有Camera,包括Game和Scene中的摄像机、反射探针、Inspector中的预览窗口。URP渲染器为每一个Camera执行:① 剔除Scene中的渲染对象;② 为渲染器构建数据;③ 执行渲染器并输出图片岛帧缓冲器。
摄像机循环:Camera Loop。
设置剔除参数 | 配置参数以决定需要剔除的光源、阴影。自定义渲染器可重写该部分。 |
剔除 | 利用上一步的参数,计算出可见渲染器、阴影簇、摄像机可见的光源的列表。剔除参数和摄像机层距离将影响剔除、渲染性能。 |
建立渲染数据 | 从剔除过程的输出、URP资源和摄像机以及运行平台的品质设置,来构建RenderingData。渲染数据指示渲染器,渲染工作量、摄像机和运行平台所需的品质。 |
设置渲染器 | 构建渲染通道列表,并根据渲染数据设定执行队列。自定义渲染器可重写该部分。 |
执行渲染器 | 执行队列中的每一个渲染通道,渲染器输出摄像机图片到帧缓冲器。 |
4.4.1、(案例)使用渲染对象渲染器特性创建自定义的渲染效果
官方文档:How to create a custom rendering effect using the Render Objects Renderer Feature
例:在角色移动到物体后方时,显示角色的剪影。
创建游戏对象的过程:① 创建一个不透明墙体;② 创建一个材质组件,并分配URP着色器,选择底色,作为角色材质;③ 创建(任意)一个游戏对象,作为角色,并分配其角色材质组件;④ 创建第二个材质组件,并分配URP着色器,选择被遮挡后显示的颜色作为底色,作为遮挡材质。
4.4.2、上述案例实操
4.4.2.1、创建渲染器特性来绘制墙后的物体
① 选择一个URP渲染器,Assets->Rendering->URPAssets_Renderer;② 在Inspector中添加渲染器特性Renderer Feature->Render Objects,选择Draw Character Behind特性;③ 该特性使用层Layer来过滤渲染的游戏对象,因此需要创建一个名为Character的新层;
④ 选择创建好的游戏对象,并将其分配到Character,点击游戏对象->Inspector中的Layer下拉框选择Character;⑤ 在刚刚创建的渲染器特性的Filters属性中,将LayMask设为Character,之后该渲染器特性只渲染Character层中的游戏对象;⑥ 在Overrides中,将Material设为已创建好的被遮挡时显示的材质,此时渲染器将把游戏对象的材质重写为所选的材质;
⑦ 为了实现只有游戏对象在物体背后时才渲染,在Overrides中,勾选Depth,并将Depth Test设为Greater,此时实现了游戏对象被遮挡时渲染为遮挡材质,但有一个问题,游戏对象会挡住自己的一部分。
4.4.2.2、创建额外的渲染器特性来避免自身透视效果
自身透视产生原因:1)当URP渲染器的不透明通道执行时,Unity渲染游戏对象的所有材质,并将depth值写入depth缓存。该过程早于Unity执行DrawCharacterBehind特性,这是由于新建的渲染器特性默认具有设为AfterRenderingOpaques的Event属性。该属性定义了Unity从对象的渲染器特性中插入渲染通道的插入点。URP渲染器在OpaqueLayerMask中绘制游戏对象的event是BeforeRenderingOpaques。2)当执行DrawCharacterBehind特性时,Unity使用DepthTest中的指定条件来进行景深测试,因此被自身遮挡的部分也会通过景深测试,因而渲染器重写了该部分的材质。
避免自身透视:① 在Assets中,将URPAssets_Renderer的Filter->OpaqueLayerMask属性中的Character层取消勾选,此时Unity将不再渲染游戏对象(除非被遮挡);② 新增一个默认渲染器特性,命名为Character;③ 在该特性中,将Filters->LayerMask属性设为Character层,此时Unity将渲染对象的角色材质(即使被遮挡),这是由于DrawCharacterBehind特性将值写入景深缓存,而当Unity执行Character特性时,游戏对象的像素出现在已经绘制的像素之上,因此游戏对象绘制在顶层;④ 在DrawCharacterBehind特性中,取消勾选Overrides->Depth->Write Depth,此时不再写入景深缓存,执行Character特性时也不再绘制被遮挡的对象。
Unity渲染过程:① 在BeforeRenderingOpaques事件中,不再渲染Character层,因为其已经被移除OpaqueLayerMask列表;② 在AfterRenderingOpaques事件中,DrawCharacterBehind特性绘制游戏对象被遮挡的部分;③ 在执行DrawCharacterBehind特性后(仍在AfterRenderingO事件中),Character特性绘制游戏对象未被遮挡的部分。
4.5、光源
在URP中,可以获得适用于大部分艺术风格的逼真光源。所有的Unity渲染管线共享通用光源功能,但每种渲染管线有一定的区别。URP不同于通用光源功能的地方在于:① 光源组件inspector(展示URP特定控制);② Universal Additional Light Data组件(存储URP专用的光源相关数据);③ URP v12支持Enlighten Realtime Global Illumination(Unity - Manual: Realtime Global Illumination using Enlighten)。
关于Unity中光源的详细内容,见Unity - Manual: Lighting。
4.5.1、光源组件
URP光源组件Inspector包含General、Emission、Rendering和Shadows。
General | Type | 当前光源类型,包括方向光Directional、点光源Point、聚光灯Spot和Area。 |
Mode | 定义光源是否烘焙、烘焙方式,包括Realtime、Mixed和Baked。 | |
Shape | Spot Angle | 以圆锥方式定义Spot光源的角度(度数)(Spot独有)。 |
Emission | Color | 选择发射光的颜色。 |
Intensity | 光源的亮度,Directional默认为0.5,其余为1。 | |
Indirect Multiplier | 设定GI系统计算出的间接光的亮度,间接光是物体反射光。小于1时,每次反射都会变得更暗。 | |
Range | 发射光传播的距离(Point和Spot独有)。 | |
Cookie | 光源投射的RGB纹理,创建光的轮廓或图案。Directional和Spot光源使用2D纹理,Point光源使用立方体贴图(Cubemap)纹理,不支持Area光源。 Cookie Size:设置cookie的尺寸,每个轴向的比例(Directional独有)。 Cookie Offset:设置cookie的偏移,可以移动cookie而不移动光源,也可以滚动cookie来实现动画化(Directional独有)。 | |
Rendering | Render Mode | 设定所选光源的渲染优先级,会影响精确性和性能。 Auto:基于当前的Quality设定和附近光源的亮度,实时决定。 Important:以每像素质量渲染,一般只用于最重要的视觉效果。 Not Important:以最快的顶点/对象光源模式渲染。 |
Culling Mask | 可以选择对象来排除该光源影响,可以只渲染特定层的对象。 | |
Shadows | Shadow Type | 定义投射Hard硬阴影、Soft软阴影、No无阴影。 |
Baked Shadow Angle | 若光源为Directional,阴影为Soft,该性质可使阴影边缘柔化,看起来更自然。 | |
Baked Shadow Radius | 若光源为Point或Spot,阴影为Soft,该性质可使阴影边缘柔化,看起来更自然。 | |
Realtime Shadows | 仅当阴影为Hard或Soft时可用,用于控制实时阴影。 Strength:控制光源投射的阴影的黑暗程度,从0~1可调,默认为1。 Bias:控制是否使用URP资源的阴影偏差UsePipelineSettings或自定义阴影偏差Custom。 Normal:控制阴影投射表面沿表面法线收缩的距离,用于避免自阴影部件的错误,仅当Bias设为Custom可用。 Near Plane:控制近裁剪面的值,0.1~10可调。该值被限制在0.1个单位或光源Range的1%中的较小值。默认为0.2。 |
4.5.2、光照模式
光源模式决定了所有使用光照设置资源Lighting Setting Assets的Scene中的所有混合光源的行为,URP支持的光源模式为Baked Indirect、Subtractive、Shadowmask。
Baked Indirect结合了实时直接光照和烘焙间接光照,为实时阴影提供了实时阴影贴图(Shadow Map),可实现逼真光照和合理的阴影精度,适用于中等水平的硬件。
Shadowmask结合了实时直接光照和烘焙间接光照,支持为远处的游戏对象(带有Shadow masks)烘焙阴影并自动混合进实时阴影贴图,因此也是最逼真、最吃资源的模式,可以通过Quality设置来配置其性能和可视精度,适用于高端硬件和部分中等水平的硬件。
Subtractive提供烘焙直接和间接光照,只为一个Directional光源渲染实时阴影,不特别提供逼真的光照结果,适用于低端硬件和风格化艺术。
为Scene设置光照模式:① 为Scene选择光照设置资源Lighting Settings Asset;② 在Inspector中,选择Mixed Lighting;③ 用下拉框选择光照模式。
4.5.3、Universal Additional Light Data
Universal Additional Light Data是URP用于内部数据存储的组件,允许URP扩展和重写Unity标准光源组件的功能。
在URP中,游戏对象包含光源组件,也必将包含Universal Additional Light Data组件。使用URP时,创建光源对象将自动添加Universal Additional Light Data组件,并且无法移除。
4.5.4、阴影
URP光源能够将一个游戏对象的阴影投射到其他对象上,阴影突出了该游戏对象的体积和位置,并为Scene添加了景深和真实感。
阴影贴图分辨率:光源的阴影贴图分辨率决定了其阴影映射的尺寸。阴影贴图越大,阴影的精确度越高,URP在阴影投射几何中捕获的细节更好。渲染阴影贴图的分辨率越高,会使阴影看起来越锐利。每个光源URP渲染的阴影贴图数量取决于光源类型:① Spot光源渲染一个阴影贴图;② Point光源渲染6个阴影贴图(立方体贴图的面数);③ Directional光源每个级联(cascade)渲染一个阴影贴图,在Project的URP资源中设置Directional光源的级联数。(URP会根据Scene中需要的阴影贴图数量和阴影图集(Shadow Atlas)尺寸来使用最好的分辨率)
阴影图集Atlas:URP渲染一帧的实时阴影时,对所有的精确光源(punctual light,例如Spot和Point)的阴影使用一个公共阴影贴图集,对Directional光源的阴影使用另一个阴影贴图集。图集的尺寸决定了Scene中阴影的最大分辨率,在Project的URP资源中设置图集的尺寸。例如,尺寸为1024x1024的图集可适用于4个512x512像素的阴影贴图或16个256x256像素的阴影贴图。
阴影图集分辨率匹配内置RP设置:在内置RP中,可以在项目的Qulity设置中选择阴影分辨率等级(Low、Medium、High、Very High)来控制阴影贴图分辨率。对每个阴影贴图,Unity基于算法使用正确的分辨率,可以在帧调试器(Frame Debugger)中找到每一个阴影贴图使用的分辨率。在URP中,可以具体规定阴影贴图集的分辨率,因此可以控制分配给阴影的内存。通过基于Scene中使用的阴影贴图数量,选择一个足够大的阴影贴图集分辨率,可以保证URP中一个精确光源的阴影的分辨率高于某个特定值。例如,若Scene中有4个Spot和1个Point,并且想要保证阴影贴图分辨率在256x256以上。此时Scene需要渲染10个阴影贴图(4个Spot四个,1个Point六个),且分辨率为256x256。因此需要选择一个1024x1024的阴影贴图集,其包含16个256x256。(若用512x512的贴图集是不够的,因为它只包含4个256x256)
阴影偏差:阴影贴图本质上是从光源角度投影的纹理。URP使用阴影偏移,因此阴影投射几何体不会有自身阴影。在URP中,每一个独立的光源组件使用参数Depth Bias、Normal Bias和Near Bias控制自身的阴影偏差。偏差设置只在设为自定义Custom时出现。高的阴影偏差会导致光从网格中“泄漏”,即在阴影和它的投射体之间有间隙,导致阴影的形状不能反映其投射体的样子。
4.5.5、反射探针
配置反射探针(Reflection Probe):Assets-> Settings-> URP-HighQuality-> Lighting-> Reflection Probes。
Probe Blending | 勾选时,启用反射探针混合。 |
Box Projection | 勾选时,启用反射探针盒体投影(Box Projection)。 |
4.5.5.1、反射探针混合
反射探针混合可以避免当一个对象进入探针盒体积时,一个反射突然出现在其上面的情况。启用反射探针混合时,当反射对象从一个体积传递到另一个时,Unity逐渐淡化探针立方体贴图的进出。URP支持前向渲染路径和延迟着色路径使用反射探针混合。
反射探针体积:每个反射探针有一个盒体积(Box Volume)。一个反射探针只影响游戏对象在盒体积中的那部分。当一个对象的某个像素不在任意反射探针体积中时,Unity使用天空盒反射。在URP中,基于像素相对于探针体积边界的位置,评估每个探针对每个独立像素的贡献。与内置RP不同,其评估一个探针对整个对象的贡献。
混合距离:每个反射探针有一个混合距离(Blend Distance)属性,这是反射盒体积的表面到盒体积中心的距离。Unity使用混合距离来决定每个反射探针的贡献。当一个对象的某个像素在反射探针体积的表面,这个像素获得该探针反射的0%。当某个像素在反射探针体积内,并且它到反射探针体积的每个面的距离都超过混合距离值时,这个像素获得100%的反射。
选择有效探针:当一个游戏对象在多个反射探针体积内时,最多两个探针可以影响该游戏对象。Unity选择有效探针的规则为:① 根据探针的重要性(Importance)属性,Unity选择两个重要性值最高的探针,忽略其他的探针;② 若重要性值相同,Unity选择两个盒体积最小的探针;③ 若重要性、盒体积都相同,Unity选择包含游戏对象表面积最大的两个探针体积的所属探针。当两个反射探针作用于一个游戏对象时,对每一个像素,Unity基于该像素到探针盒体积表面的距离以及混合距离来计算每个探针的权重(若该像素离盒体积表面很近,且两个探针的权重总和小于1,Unity将把剩下的权重分配给天空盒反射)。若这两个盒体积都包含该像素,且到盒体积表面的距离大于混合距离,那么① 若两个反射探针的重要性属性值相同,Unity以相同的权重混合每个探针的反射;② 若某个反射探针的重要性属性值更高,Unity只使用该探针的反射。
4.5.6、光源层
光源层(Light Layer)用于配置某个光源作用于特定的游戏对象。
启用光源层:在URP资源的Lighting部分中,点击右上角三点,选择Show Additional Properties;② 在展开的页面中,勾选Light Layer(勾选后光源组件将出现新的属性,即光源层Light Layer和自定义阴影层Custom Shadow Layer)
编辑光源层名称:在Project Settings-> Graphics-> URP Global Settings中的Light Layer Names(3D)部分,编辑光源层的名称。
光源层的用法(案例):① 在项目中启用光源层;② 创建两个点光源,分别叫A和B,再创建两个对象,分别叫C和D;③ 将任意两个光源层分别命名为L1和L2;④ 将A光源改为绿色,将B光源改为红色,此时两个光源对两个对象都有影响;⑤ 将A的Light-> General-> Light Layer清除设置,再改为L1,同理将B的改为L2,将对象C的Mesh Renderer-> Additional Settings-> Rendering Layer Mask的所有选项清除A,同理将B的清除D;完成后光源A只影响D,不影响C。
-> 第⑤步 ->
自定义阴影层的用法:在上例中,光源A不影响C,C没有来自光源A的阴影。自定义阴影层Custom Shadow Layer可以配置C投射来自光源A的阴影。步骤:① 选择光源A,在Shadow中勾选Custom Shadow Layer,出现Layer属性;② 在Layer中选择C所属的光源层,即L2;完成后,光源A不影响C,但是C有了来自光源A的投影。
4.5.7、Lens Flare Data Asset
SRP(可编程RP)包含镜头光晕数据资源(Lens Flare Data Asset),可用于控制Scene中镜头光晕的出现。这是SRP等效于内置RP的光晕资源,与SRP不兼容。创建镜头光晕数据资源:Assets-> Create ->Lens Flare(SRP)。使用时,将资源分配到镜头光晕组件的镜头光晕数据属性中。
4.5.7.1、镜头光晕组件
镜头光晕(Lens Flare)组件包含如下属性:Type、Color、Tansform、Axis Transform、Distortion和Multiple Elements。
Type | Type | 包含图像Image、圆Circle、多边形Polygon。每个Type有不同的属性。 |
Image | Flare Texture:镜头光晕元素使用的纹理。 Preserve Aspect Ratio:固定光晕纹理的宽和高(纵横比),可用Distortion更高。 | |
Circle | Gradient:控制圆形光晕的梯度的偏移,从0~1可调。 Falloff:控制圆形光晕的梯度的衰减,从0~1可调。0表示没有衰减,1表示衰减均匀地分布在圆上。 Inverse:使梯度方向反转。 | |
Polygon | Gradient:控制多边形光晕的梯度的偏移,从0~1可调。 Falloff:控制多边形光晕的梯度的衰减,从0~1可调。0为无衰减,1为均匀分布。 Side Count:多边形光晕的边数。 Roundness:决定多边形光晕边缘的光滑度,从0~1可调。0为锐利多边形,1为圆。 Inverse:使梯度方向反转。 | |
Color | Tint | 改变镜头光晕的色调。若该组件是加在光源上,跟随光源的色调。 |
Modulate By Light Color | 允许灯光颜色影响镜头光晕,只在加在Point/Spot/Area光源的镜头光晕组件上的资源可用。 | |
Intensity | 控制强度。 | |
Blend Mode | 选择该资源创建的镜头光晕的混合模式:添加Addictive、屏幕Screen、预乘Premultiplied、Lerp。 | |
Transform | Position Offset | 定义镜头光晕相对于其源头的屏幕空间Screen Space上的位置偏移。 |
Auto Rotate | 启用镜头光晕自动旋转,相对于屏幕上的角度(会重写Rotation参数)。(为确保镜头光晕可以旋转,要给Starting Position设一个大于0的值。) | |
Rotation | 旋转镜头光晕。该值以度数为单位。 | |
Size | 调整镜头光晕的大小Scale。(在Image类型的光晕且启用Preserve Aspect Ration参数时,该性质不可用。) | |
Scale | 控制镜头光晕在世界坐标World Space的尺寸。 | |
Axis Transform | Starting Position | 镜头光晕相对于其源头的位置(该值在屏幕空间中执行)。 |
Angular Offset | 控制镜头光晕的角度偏移,相对于其当前位置。该值以度数为单位。 | |
Translation Scale | 现在镜头光晕偏移的大小,以XY坐标形式。例如,(1,0)创建水平光晕,(0,1)创建垂直的光晕。同时,可以控制光晕的移动速度,例如,(0.5, 0.5)使光晕像是以一般的速度移动。 | |
Distortion | Enable | 启用光晕扭曲。 |
Radial Edge Size | 从屏幕边缘控制扭曲效果的尺寸。 | |
Radial Edge Curve | 以曲线来混合扭曲效果,横轴为从屏幕中心到屏幕边缘。 | |
Relative To Center | 使扭曲与屏幕中心相关。否则,扭曲与镜头光晕的位置相关。 | |
Multiple Elements | Enable | 启用时,屏幕中可以有多光晕元素。 |
Count | 决定Unity生成的完全相同的光晕个数。值1与单光晕元素相同。 | |
Distribution | 生成多光晕元素的方式:Uniform、Curve和Random。 | |
Length Spread | 控制如何展开多光晕元素。 | |
Uniform | Colors:资源应用到这些光晕上的颜色范围。 Rotation:每个旋转的角度增量(以度数为单位)。 | |
Curve | Colors:资源应用到这些光晕上的颜色范围。(可使用Position Spacing曲线控制每个光晕被影响的范围。) Position Variation:更改Lens Spread中光晕元素的排列位置。 Rotation:曲线上分布的每个光晕均匀旋转的角度。 Scale:控制光晕元素的尺寸范围。 | |
Random | Seed:产生随机的随机种子。 Intensity Variation:控制光晕元素间的亮度差异(值过大会使某些光晕不可见) Colors:资源应用到这些光晕上的颜色范围。(该性质基于Seed值) Position Variation:控制这些光晕的位置。X值沿Length Spread的轴排列,0代表光晕位置没变化。Y值基于Seed值,沿屏幕空间垂直轴分布。 Rotation Variation:基于Seed值,控制这些光晕的选择差异。(Rotation和Auto Rotation继承此性质) Scale Variation:基于Seed值,控制这些光晕的大小。 |
4.6、摄像机Cameras
Unity中的摄像机与真实世界的类似,捕获三维空间中的对象的视角,并将其扁平化在二维平面中展示。URP中的摄像机是基于Unity的标准摄像机功能,但有一些不同点:① Universal Additional Camera Data组件,扩展摄像机的功能并且允许URP存储额外的摄像机相关数据;② Render Type设置,定义URP中Base和Overlay类型的摄像机;③ Camera Stacking系统,允许堆叠多个摄像机的输出,即合并为单个输出;④ Volume系统,允许基于一个给定的Scene中的变形位置,为摄像机应用后处理效果;⑤ Camera组件,在Inspector中展现URP独有的性质。摄像机的基本介绍:摄像机 - Unity 手册。
4.6.1、Universal Additional Camera Data
Universal Additional Camera Data是URP用于内部数据存储的组件,允许URP扩展和重写Unity标准摄像机组件的功能和展示。
在URP中,带有摄像机组件的游戏对象必定带有Universal Additional Camera Data组件。项目使用URP时,当创建一个摄像机时,Unity自动添加Universal Additional Camera Data组件,并且该组件无法移除。
若不使用脚本去控制/自定义URP,可以在脚本中这样写来访问Universal Additional Camera Data组件:(API文档:Class UniversalAdditionalCameraData)
var cameraData = camera.GetUniversalAdditionalCameraData();
若在脚本中需要频繁访问Universal Additional Camera Data,应该存储对它的引用,避免不必要的CPU动作。
4.6.2、Render Type
URP中有两种类型的摄像机。Base摄像机是渲染一个渲染对象的通用摄像机,例如屏幕、纹理。Overlay摄像机在其他摄像机的输出上进行渲染,可以混合一个Base摄像机和一个或多个Overlay摄像机的输出流(称为摄像机堆叠Camera Stacking)。
摄像机类型修改:一、可以在摄像机组件Inspector中的Render Type进行摄像机类型的修改。二、在脚本中修改,在摄像机的组件Universal Additional Camera Data中,将进行如下修改:
var cameraData = camera.GetUniversalAdditionalCameraData();
cameraData.renderType = CameraRenderType.Base; // Base类型摄像机
Base摄像机:URP中的默认摄像机类型,是渲染一个给定渲染目标的通用摄像机。在URP中,Scene中至少要一个Base摄像机才能渲染事物。Base摄像机可以独立使用,也可以在相机堆叠中使用。在Scene中,一个激活的摄像机挂件附近将显示一个摄像机图标。
Overlay摄像机:Overlay摄像机在其他摄像机的输出之上渲染,可以创建特效,例如2D UI中的3D对象、汽车驾驶舱。Overlay摄像机必须使用摄像机堆叠系统与一个或多个Base摄像机组合使用,不能被独立使用。不在摄像机栈(Camera Stack)中的Overlay摄像机不参与渲染循环的任何步骤,是一个孤立摄像机。在Scene中,一个激活的摄像机挂件附近将显示一个Overlay摄像机图标。(不能对独立的Overlay摄像机使用后处理,只可以对Base摄像机或摄像机堆叠使用。)
(Base摄像机决定了摄像机栈中的大部分性质。由于Overlay摄像机只能在摄像机栈中使用,只能使用摄像机的部分性质:Projection、FOV Axis、Field of View、Physical Camera Properties、Clipping plans、Renderer、Clear Depth、Render Shadow、Culling Mask、Occlusion Culling。可以使用脚本修改被隐藏的不可用性质,但对摄像机栈的视觉输出没人任何影响。)
4.6.3、多摄像机工作
4.6.3.1、摄像机栈
一个摄像机栈由一个Base摄像机和一个或多个Overlay摄像机组成,并将Base摄像机的输出重写为摄像机栈中所有摄像机输出的混合。因此,可以对Base摄像机的输出进行任何操作,也可以对摄像机栈的输出进行任何操作,例如,将摄像机栈渲染到给定目标、应用后期处理等。
URP在摄像机内执行优化,例如渲染顺序优化以减少过度绘制(overdraw)。然而,在摄像机栈内可以有效地定义这些摄像机的渲染顺序,要注意避免冗余。(官方案例:URP Samples)
新增一个摄像机到栈中:一、① 在Scene中新建一个Base摄像机;② 在Scene中新建一个Overlay摄像机;③ 选中建好的Base摄像机,在Stack属性中选择建好的Overlay摄像机。二、脚本方式,在Base摄像机的Universal Additional Camera Data组件中添加:
var cameraData = camera.GetUniversalAdditionalCameraData();
cameraData.cameraStack.Add(myOverlayCamera);
从栈中移除一个摄像机:一、① 选择一个在摄像机栈中的Base摄像机;② 在其Stack属性中删除想要移除的Overlay摄像机。二、脚本方式,在Base摄像机的Universal Additional Camera Data组件中删除:
var cameraData = camera.GetUniversalAdditionalCameraData();
cameraData.cameraStack.Remove(myOverlayCamera);
改变摄像机栈中的摄像机顺序:一、① 选择一个在摄像机栈中的Base摄像机;② 在其Stack属性中拖动摄像机。二、脚本方式。
将同一个Overlay摄像机添加到多个不同的栈中:一、① 创建一个摄像机栈;② 创建一个新的Base摄像机;③ 在其Stack属性中添加想要共用的Overlay摄像机。二、脚本方式:在新建的Base摄像机的Universal Additional Camera Data组件中添加:(与新建一个摄像机栈过程一致)
var cameraData = camera.GetUniversalAdditionalCameraData();
cameraData.cameraStack.Add(myOverlayCamera);
4.6.3.2、从多个摄像机渲染同一目标
在URP中,多个Base摄像机或摄像机栈可以渲染同一个目标,可以渲染出分屏效果。
如果多个Base摄像机或摄像机栈渲染同一个目标,Unity将重叠区域的像素绘制多次,最后在其上绘制最高优先级的摄像机或摄像机栈。(可以使用Base摄像机的Output Target属性定义渲染目标,Viewport Rect属性定义渲染目标的渲染区域,详见Unity - Manual: Camera component)
设置分屏渲染:① 创建一个Base摄像机;② 确保该Base摄像机的Output Target属性设为Camera,并将Viewport Rect属性设为X:0 Y:0 W:0.5 H:1;③ 创建另一个Base摄像机,确保其Output Target属性设为Camera,并将Viewport Rect属性设为X:0.5 Y:0 W:0.5 H:1。此时,Unity将在屏幕左手边渲染第一个摄像机,在屏幕右手边渲染第二个摄像机。此操作在Camera的脚本中实现为:
myUniversalAdditionalCameraData.rect = new Rect(0f, 0f, 0.5f, 1f);
4.6.3.3、渲染到渲染纹理
在URP中,摄像机可以渲染到屏幕或者渲染纹理(Render Texture)。渲染到屏幕是默认且最常见的场景,渲染到渲染纹理可以创建一个类似闭路电视监视器的特效。
若一个摄像机是渲染到渲染纹理的,那必须有第二个摄像机将这个渲染纹理渲染到屏幕。在URP中,所有渲染到渲染纹理的摄像机是在所有的渲染到屏幕的摄像机之前执行渲染循环,这确保了渲染纹理能渲染到屏幕上。
将渲染纹理渲染到屏幕:① 在项目Assets-> Create -> Render Texture中创建一个渲染纹理;② 创建一个材质Material,并将渲染纹理拖到材质的Base Map域中;③ 创建一个四边形对象,将该材质拖到四边形上;④ 创建一个Base摄像机,并将该摄像机的Output Target设为Texture(纹理),将渲染纹理拖到Output的Texture域中;⑤ 创建另一个Base摄像机,将该摄像机对准四边形对象。(第一个摄像机将其视野渲染为渲染纹理,第二个摄像机将包含渲染纹理的视野渲染到屏幕。)设置摄像机的Output Target可以用脚本方式,即设置Universal Additional Camera Data组件:
myUniversalAdditionalCameraData.cameraOutput = CameraOutput.Texture;
myCamera.targetTexture = myRenderTexture;
4.6.4、清理、渲染顺序、过度绘制
4.6.4.1、清理
在URP中,摄像机的清理行为基于其渲染类型。
Base摄像机:在渲染循环的开始,Base摄像机可以将其颜色缓存(Color Buffer)清理为天空盒或纯色,或者使用一个未初始化的颜色缓存(可以使用Base摄像机的Background Type属性定义)。注意,在不同平台上,未初始化颜色缓存的内容不一样,有的平台其内容是上一帧的数据,有的平台则包含未初始化的存储。只有当摄像机绘制每个像素到颜色缓存中并且避免不必要的清理行为时,才使用未初始化的颜色缓存。在每个渲染循环的开始,Base摄像机都会清理景深缓存(Depth Buffer,又叫Z-Buffer,用16bit存储一个像素的深度,与该像素到摄像机的距离有关)。
Overlay摄像机:在渲染循环的开始,Overlay摄像机从摄像机栈中之前的摄像机获得一个颜包含颜色数据的颜色缓存,不清理颜色缓存的内容。在渲染循环的开始,Overlay摄像机从摄像机栈中之前的摄像机获得一个包含景深数据的景深缓存。可以使用Overlay摄像机的Clear Depth属性来控制清理景深缓存,当其设为true时,Overlay摄像机清理景深缓存,并将其视野绘制到颜色缓存的顶部;当其设为false时,Overlay摄像机将在绘制视野到颜色缓存之前对景深缓存进行测试。
4.6.4.2、渲染顺序、过度绘制
渲染顺序:在URP中,当Scene中包含多个摄像机时,Unity以可预见的顺序执行摄像机剔除和渲染操作,在每一帧中执行一次如下操作:① Unity获取Scene中所有的激活Base摄像机的列表;② Unity根据这些摄像机渲染到渲染纹理还是屏幕,将之分成两组;③ Unity将渲染到渲染纹理的Base摄像机按优先级排序,高优先级的Base摄像机后渲染;④ 对每个渲染到渲染纹理的Base摄像机进行:剔除该Base摄像机,将其渲染到渲染纹理,对该Base摄像机所属的摄像机栈中的每个Overlay摄像机:先剔除该Overlay摄像机,再将Overlay摄像机渲染到渲染纹理;⑤ Unity将渲染到屏幕的Base摄像机按优先级排序,高优先级的Base摄像机后渲染;⑥ 对每个渲染到屏幕的Base摄像机进行:剔除该Base摄像机,将其渲染到屏幕,对该Base摄像机所属的摄像机栈中的每个Overlay摄像机:先剔除该Overlay摄像机,再将Overlay摄像机渲染到屏幕。(Unity可以在一帧中多次渲染同一个Overlay摄像机,因为其可能属于多个摄像机栈,或者在同一个摄像机栈中出现多次。出现这种情况时,Unity只是简单地重复剔除/渲染排序的操作,即将该重复的Overlay摄像机重新进行一次渲染排序。)(在URP12.1.14中,若使用2D渲染器,Overlay摄影机将不会执行其渲染循环。 )
过度绘制(Overdraw):URP在摄像机中会执行渲染排序优化来减少过度绘制,因此在使用摄像机栈定义摄像机渲染顺序时,要避免过度绘制。当一个摄像机栈中的多个摄像机渲染到同一个渲染目标时,Unity为每一个摄像机绘制渲染目标的每个像素。此外,若多个Base摄像机或摄像机栈渲染到同一个渲染对象的同一个区域,Unity也会多次渲染重叠区域的每个像素。(过度绘制可以在Frame Debugger中找到,用来优化摄像机栈。)
4.6.5、抗锯齿(Anti-aliasing)
锯齿是采样器对真实世界信息进行采样并数字化时产生的副作用,当Unity渲染一条线时,将会出现锯齿,像素与屏幕上预期出现的路径不完全一致。
URP有多种方法抗锯齿,每个方法的有效性和资源需求不同:快速近似抗锯齿(Fast Approximate Anti-alliasing, FXAA)、子像素形态抗锯齿(Subpixel Morphological Anti-aliasing, SMAA)、多重采样抗锯齿(Multisample Anti-aliasing, MSAA)。
FXAA:FXAA使用全屏通道进行像素级的边缘光滑,是URP中资源需求最低的抗锯齿技术。为摄像机选择FXAA:选择一个摄像机,在其Inspector中的Rendering-> Anti-aliasing属性选择FXAA。
SMAA:SMAA在图像的边界中找到花样,并根据找到的花样混合这些边界上的像素,比FXAA的结果更好。为摄像机选择SMAA:选择一个摄像机,在其Inspector中的Rendering-> Anti-aliasing属性选择SMAA。
MSAA:MSAA对每个像素的景深和模板值(stencil value)进行采样,并将这些采样组合以生成最终像素。MSAA解决了空间锯齿问题,并对于三角形边缘锯齿有更好的解法,然而不能解决着色器锯齿问题,例如反射或纹理锯齿。MSAA是最耗硬件资源的抗锯齿方案,但是,当在没有使用后期处理抗锯齿或自定义渲染功能的Tiled GPU上运行时,MSAA是比其他抗锯齿方案更节省资源的选项。MSAA是硬件抗锯齿方案,可以使用后期处理等其他方案共用。启用MSAA:打开URP资源,在Quality-> Anti Aliasing(MSAA)中选择合适的MSAA等级。(更多MSAA设置:URP Quality)
4.6.6、相机组件参考
根据摄像机渲染类型Render Type的不同,Inspector会展示不同的属性。
Base摄像机:Projection、Physical Camera、Rendering、Stack、Environment和Output。
Overlay摄像机:Projection】Physical Camera、Rendering和Environment。
4.6.6.1、Projection
Projection | 切换相机模拟透视的功能。 Perspective:摄影机将在透视不变的情况下渲染对象。 Orthographic:摄像机将在正交、无透视情况下渲染对象。 |
Field of View Axis | 设置Unity测量摄像机视野所沿的轴,可选项为Vertical和Horizontal。 (仅在Perspective下可见该属性) |
Field of View | 设置摄像机视角的宽度,沿着所选的轴进行测量,以度数为单位。 (仅在Perspective下可见该属性) |
Size | 设置摄像机的视窗大小。(仅在Orthographic下可见该属性) |
Clipping Planes | 设置摄像机渲染起始到终止的距离。 Near:相对于将要绘制的摄像机的最近点。 Far:相对于将要绘制的摄像机的最远点。 |
Physical Camera | 启用摄像机的Physical Camera功能。 当启用Physical Camera时,Unity用模拟真实世界摄像机的属性(Focal Length、Sensor Size和Lens Shift)来计算Field of View。 (仅在Perspective下可见该属性,勾选后才可见Physical Camera性质) |
4.6.6.2、Physical Camera
Camera Body | Sensor Type | 定义模拟的真实摄像机类型,从列表选择。选择后,Unity自动设置Sensor Size、X和Y为正确值。若手动设置Sensor Size值,该值将自动改为Custom。 |
Sensor Size | 设置摄像机的传感器尺寸,单位为mm。(可以自定义该值。) X:设置摄像机传感器的水平尺寸。 Y:设置摄像机传感器的垂直尺寸。 | |
Gate Fit | 改变分辨率门(resolution gate,Game View的尺寸/长宽比)相对于片门(film gate,Physical Camera传感器的尺寸/长宽比)的尺寸。(详见:Unity - Manual: Using Physical Cameras) Vertical:使分辨率门匹配片门的高度。若传感器长宽比大于Game View的长宽比,Unity将把图片的左右边缘裁掉。若传感器长宽比小于Game View的长宽比,Unity会过扫描(overscan)图片的左右边缘。(选择这个设置后再修改传感器宽度X,对渲染的图像没有任何影响。) Horizontal:使分辨率门匹配片门的宽度。若传感器长宽比大于Game View的长宽比,Unity会过扫描图像的上下边缘。若传感器长宽比小于Game View的长宽比,Unity将把图片的上下边缘裁掉。(选择这个设置后再修改传感器高度Y,对渲染的图像没有任何影响。) Fill:使分辨率门匹配片门的高度或宽度,选择相对较小的维度进行匹配,即将分辨率门扩大后填充片门,将图像边缘裁掉。 Overscan:使分辨率门匹配片门的高度或宽度,选择相对较大的维度进行匹配,将图像过扫描。 None:忽略分辨率门,只使用片门。拉伸渲染的图像以匹配Game View的纵横比。 | |
Lens | Focal Length | 设置摄像机传感器和摄像机镜片之间的距离,单位为mm。 值越低,Field of View视野越开阔,反之亦然。 (当修改这个值时,Unity会自动更新Field of View属性。) |
Shift | 从中心水平或垂直平移镜片,值为传感器尺寸的倍数。例如,沿X轴平移0.5意味着在水平方向上移动了0.5x传感器宽度的距离。(可以平移镜片来校正摄像机与对象成一定角度时造成的失真。)沿任一轴平移镜片将使摄像机视椎体倾斜(frustum oblique)。 X:设置镜片对于传感器的水平偏移。 Y:设置镜片对于传感器的垂直偏移。 |
4.6.6.3、Rendering
Renderer | 摄像机使用的渲染器。 |
Post Processing | 启用后期处理效果。 |
Anti-Aliasing | 选择摄像机用于后期处理抗锯齿的方式(只有Base摄像机可用)。除时域抗锯齿Temporal Anti-aliasing外,摄像机可以在后期处理抗锯齿的同时使用MSAA。以下为可用的抗锯齿选项: None:可以处理MSAA,但是不处理任何后期处理抗锯齿。 FXAA:在全屏通道上进行像素级的边缘光滑处理。 SMAA:找出图像的边缘花样,并根据花样来混合边缘的像素。 |
Quality | SMAA的质量,可选项为Low、Medium和High,Low和High之间的资源需求差别很小。(只在Anti-Aliasing设为SMAA时可见) |
Stop NaNs | 勾选后,将NaN值替换为黑像素点(只有Base摄像机可见)。(可防止一定程度上的崩溃,但是该功能耗费资源,只有无法处理的NaN问题时可用) |
Dithering(抖动) | 勾选后,将在最终渲染上使用8-bit抖动,有助于减少宽梯度和弱光区域的条纹(只有Base摄像机可见)。 |
Clear Depth | 启用后,将在渲染时清理之前的摄像机的景深(只有Overlay摄像机可见)。 |
Render Shadows | 启用阴影渲染。 |
Priority | 高优先级摄像机绘制在低优先级摄像机之上,范围为-100~100。(只有Base摄像机可见)。 |
Opaque Texture | 控制摄像机是否创建一个摄像机不透明纹理(CameraOpaqueTexture,渲染视野的副本),(只有Base摄像机可见)可选项为: Off:不创建摄像机不透明纹理。 On:创建摄像机不透明纹理。 Use Pipeline Settings:RP资源决定此设置的值。 |
Depth Texture | 控制摄像机是否创建一个摄像机景深纹理(CameraDepthTexture,渲染景深值的副本),(只有Base摄像机可见)可选项为: Off:不创建摄像机景深纹理。 On:创建摄像机景深纹理。 Use Pipeline Settings:RP资源决定此设置的值。 |
Culling Mask | 选择摄像机渲染到的Layer。 |
Occlusion Culling | 启用遮挡剔除(Occlusion Culling)。 |
4.6.6.4、Stack
只有Base摄像机可用。(详见4.6.3)
摄像机栈可以混合多个摄像机的结果,包含一个Base摄像机和多个Overlay摄像机。
可以使用栈属性添加Overlay摄像机,这些摄像机将以栈中的顺序进行渲染。
4.6.6.5、Environment
Background Type | 控制渲染循环开始时,初始化颜色缓存的方式(只有Base摄像机可见)。详见4.6.4.1。 Skybox:将颜色缓存初始化为天空盒。若没有天空盒,则默认为背景色。 Solid Color:初始化颜色缓存为给定的纯色。选择后将出现新属性Background,在渲染开始前,摄像机将把颜色缓存清理为Background指定的颜色。 Uninitialized:不初始化颜色缓存。对特定对象的加载动作将是DontCare,而不是Load或Clear。DontCare意味着之前的渲染对象内容不必保留。(只有在摄像机或摄像机栈需要绘制到颜色缓存中的每个像素的情况下,优化性能使用,否则摄像机未绘制的像素的行为时未定义的。)(在编辑器和播放器上的结果可能不同,因为编辑器不在分块延迟渲染的GPU上运行,如果在TBDR GPU上使用,会导致未初始化的块内存和未定义内容) |
Volumes | 定义体积Volumes影响摄像机的方式。 Update Mode:更新体积的方式,可选项为Every Frame(渲染的每帧更新)、Via Scripting(仅在脚本激发时更新)、Use Pipeline Settings(使用RP的默认设置)。 Volume Mask:通过Layer Mask设置影响该摄像机的Volumes。 Volume Trigger:为Volume系统指定一个处理摄像机位置的位置变化Transform。例如,若使用了第三人称角色,将该值设为角色的Transform。随后摄像机使用该角色进入的Volume的后期处理和Scene设置。若不分配,则使用该摄像机自身的Transform。 |
4.6.6.6、Output
只有Base摄像机可用。当Base摄像机的Render Target为Texture时(渲染纹理),以下属性在Inspector中不出现:Target Display、HDR、MSAA和Allow Dynamic Resolution。这是因为这些属性由渲染纹理决定,在渲染纹理资源中修改。
Output Texture | 若填了该值,将渲染到渲染纹理,否则渲染到屏幕。 |
Target Display | 定义渲染到的外部设备,取值为1~8。(仅在Render Target为Screen时可见) |
Target Eye | 选择摄像机的目标眼。 Both:允许选定摄像机的XR渲染。 None:禁用选定摄影机的XR渲染。 |
Viewport Rect | 用4个值指示该摄像机在屏幕上绘制的位置,以Viewport坐标测量,从0~1。(仅在Render Target为Screen时可见) X:用于绘制摄像机视野的起始水平位置。 Y:用于绘制摄像机视野的起始垂直位置。 W:width,摄像机输出在屏幕上的宽度。 H:Height,摄像机输出在屏幕上的高度。 |
HDR | 启用HDR。(仅在Render Target为Screen时可见) |
MSAA | 启用MSAA。(仅在Render Target为Screen时可见) |
Allow Dynamic Resolution | 启用URP动态分辨率。(仅在Render Target为Screen时可见) |
4.7、后期处理
URP包含了后期处理效果的集成实现,因此不需要安装额外的包,但与Post Processing Stack v2包不兼容,在OpenGL ES 2.0中不支持后期处理。URP在后期处理中使用Volume框架。
4.7.1、配置后期处理
在新Scene中配置后期处理:① 选择一个摄像机,勾选Post Processing;② 在Scene中添加一个有Volume组件的对象,这里使用GlobalVolume,选择GameObject-> Volume-> Global Volume;③ 在GlobalVolume对象的Inspector中,在Volume组件中点击New,创建一个新的Profile;④ 在Volume组件中添加Volume Overrides来添加后期处理效果。(可以在Volume组件的Overrides中调整后期处理的设置)
移动设备上的后期处理:后期处理会占用大量的帧时间,如果在移动设备上使用URP,以下特效是高效的:Bloom、Chromatic Aberration、Color Garding、Lens Distortion和Vignette。
VR上的后期处理:在VR应用中,某些特效会导致恶心和方向障碍。为了较少高速移动或快步伐应用中的不良反应,使用Vignette特效,而不是Chromatic Aberration、Lens Distortion和Motion Blur。
4.7.2、Volume
URP使用Volume框架,Volume可以基于摄像机相对于每个Volume的位置,重载或扩展Scene性质。URP使用Volume框架实现后期处理特效。
URP为Volume设计了专门的对象:Global Volume、Box Volume、Sphere Volume和Convex Mesh Volume。Volume的模式分为Global和Local。当模式为Global,Volume会应用Scene中每个地方的摄像机;当模式为Local,Volume只影响在碰撞体Collider内的摄像机。可以为任何游戏对象添加Volume组件,
一个Scene可以包含多个带Volume组件的游戏对象,一个游戏对象也可以有多个Volume组件。Volume组件引用一个Volume Profile,该对象包含了Scene的性质,包括每个性质的默认值。Volume Overrides用于改变或扩展Volume Profile中的默认性质。
运行时,URP会遍历Scene中所有被添加到激活的游戏对象上的启用的Volume组件,并且,根据最终的Scene设置来决定每个Volume的贡献。URP使用摄像机位置和Volume组件性质来计算贡献,对所有非零贡献的Volume进行插值计算得出最终的特性值。
Volume组件性质:Volume组件包含了控制影响摄像机方式的性质以及控制与其他Volume交互方式的性质。
Mode | URP所用的计算该Volume是否影响摄像机的方式。 Global:Volume没有边界,可以影响Scene中的每个摄像机。 Local:可为Volume定义边界,只影响在边界内的摄像机。为Volume所属的游戏对象添加一个碰撞体Collider,就可以使用边界。 |
Blend Distance | 距开始混合的Volume碰撞体的最远距离。0值意味着进入瞬间就应用Volume的重载Override。(只在Local模式下可见。) |
Weight | Volume在Scene上的影响大小。此倍数用于摄像机位置和Blend Distance计算出的值上。 |
Priority | 当多个Volume对Scene有相同的影响时,高优先级的Volume先使用。 |
Profile | Volume Profile资源包含了存储URP用于处理此Volume的性质的Volume组件。 |
Volume Profile:Profile域存储一个Volume Profile,是一个包含了URP用于渲染Scene的性质的资源。可以编辑这个Volume Profile,或分配别的Volume Profile给Profile域,或通过New/Clone按钮来创建/克隆一个Volume Profile。
使用Local Volume:① 创建一个盒碰撞体GameObject-> Volume-> Box Volume;② 为该Volume新建一个Profile(在Profile域点击New),URP会创建新的Volume Profile,并这个Volume组件增加Add Override按钮;③ 确保该Volume有较高的优先级,避免其他Volume重载的影响,即使Priority保持较大的值;④ 点击Add Override,选择一个后期处理特效;⑤ 在碰撞体Collider组件中,调整Center和Size,确保该碰撞体覆盖想要后期处理特效发生的位置(碰撞体的Is Trigger要保证勾选上)。此时,当摄像机进入Volume的盒碰撞体时,URP将会从Box Volume中使用Volume Overrides。
4.7.2.1、Volume Profile
Volume Profile是一个可编辑脚本对象(保存数据的容器),包含了Volume使用的性质,用于决定其影响的摄像机渲染Scene环境的方式。Volume引用其Profile域中的Volume Profile,并使用其中的数据值。
Volume Profile将Scene性质数据组织成控制不同环境设置的结构。这些结构都包含了可用的默认值,但可以用Volume Overrides来重载这些值,自定义环境设置(environment settings)。
创建Volume Profile:当创建一个Scene Settings(Rendering-> Scene Settings)时,Unity自动创建并连接一个Volume Profile;或者,手动创建一个Volume Profile,Assets-> Create-> Volume Profile。
定制Volume Profile:① 打开一个Volume Profile:一、在Assets文件夹中,选中一个Volume Profile;二、在Inspector中,选择一个带有Volume组件的游戏对象,且该Volume组件设置了Volume Profile;② 当在Inspector中查看Volume Profile时,只能看到其中包含的被Volume重写的值,其他值都被隐藏;③ 必须添加Volume Override组件来编辑Volume Profile中的默认属性,在Inspector中点击Add Override按钮来添加想要的Volume Override(例如,添加Motion Blur这个Volume Override后,将展示URP中与该特效相关的性质)。
4.7.2.2、Volume Overrides
Volume Override可以修改或扩展Volume Profile中的默认性质,URP通过其实现后期处理效果。在一个Volume Override中,每个性质左边的勾选框可以启用/禁用特定的性质。禁用某个性质后,URP将使用该性质的Volume默认值。
添加一个Volume Override:① 选择带有Volume组件的游戏对象;② 在Inspector中,点击Add Override按钮。
4.7.3、特效表
详见:Effect List | Universal RP | 12.1.12 (unity.cn)
Ambient Occlusion | 加深折痕、空洞、相交处和贴近的两个面等闭塞(真实世界中环境光被遮挡的暗处)。在URP中屏幕空间Ambient Occlusion(SSAO)是一个渲染器特性,适用于URP提供的每个着色器或自定义不透明着色器。 |
Bloom | 创建从图像中明亮区域边界延伸出来的光线条纹。包含Lens Dirt特性,可以用全屏范围的污迹或灰尘来衍射Bloom特效。 |
Channel Mixer | 修改每个颜色输入通道对输出通道整体混合的影响。例如,若提高绿色通道对红色通道整体混合的影响,那么最终图像所有的绿色区域(包括中性/单色)都更偏红色。 |
Chromatic Aberration | 创建沿着明暗分界线的彩色条纹。模拟真实相机在镜头无法将所有颜色汇聚到同一点时产生的颜色失真。 |
Color Adjustments | 调整最终渲染图像的整体色调、亮度和对比度。 |
Color Curves | 分级曲线是特定范围内调整色调、饱和度或光度的高级方法。通过调整8个曲线,可以获得特定色调替换、某种亮度去饱和等效果。 |
Depth Of Field | 景深组件模拟相机镜片的对焦性质。真实世界中的摄像机只能清晰聚焦特定距离上的对象,近处远处都会无法聚焦。模糊会给呈现出视觉上的距离感,并散焦(图像亮部失焦)。URP提供了两种景深模式:Gaussian和Bokeh。 |
Film Grain | 模拟胶片上的随机光学纹理。 |
Lens Distortion | 扭曲最终图像来模拟真实世界镜头。类似鱼眼? |
Lift Gamma Gain | 三原色分级,使用Lift(暗部)、Gamma(灰部)和Gain(亮部)三个轨迹球来调整图像的色调,每个轨迹球影响的范围不同,还提供一个滑块来调整该范围内的颜色亮度。 |
Motion Blur | 模拟真实世界中物体速度过快/曝光时间过长产生的运动模糊。URP仅模糊摄像机运动。 |
Panini Projection | 用于渲染视野很大的Scene中的透视场景。帕尼尼投影是一种圆柱形投影,保持垂线的垂直、笔直,同时保持穿过图像中心的径向线是笔直的。 |
Shadows Midtones Highlights | Shadows(阴影)、Midtones(中间调)和Highlights(高光)三个轨迹球分别控制渲染的阴影、中间调和高光,比Lift Gamma Gain特效更精确地定义阴影、中间调和高光的对比度(Tonal Range,灰阶范围、亮度范围、动态范围)。 |
Split Toning | 根据图像不同区域的亮度进行上色,获得更独特的外观,可以给阴影和高光添加不同的色调。 |
Tonemapping | 色调映射是将图像的HDR值映射到一个新范围的值的过程。可以使低HDR的图像看起来具有高HDR。 |
Vignette | 渐晕是指与图像中心相比,图像边缘变暗和/或去饱和。可以将注意力汇聚到图像中心。 |
White Balance | 白平衡可以删除不现实的颜色投影,使现实生活中看起来是白色的物体在最终图像中渲染为白色,也可以用于修改图像的色温,使之更冷或更暖。 |
Lens Flare | 渲染一个镜头光晕。 |
4.8、着色器和材质
着色器的相容性:为内置RP写的Lit着色器和自定义Lit着色器与URP不兼容。为内置RP写的Unlit着色器与URP兼容。
选择一个着色器:URP使用基于物理的渲染(PBR)。渲染管线提供了可以模拟真实世界的预建着色器。PBR材质提供了一组参数,使创作者能够在不同的材料类型和不同的照明条件下实现一致性。URP的Lit着色器适用于模拟真实世界的大部分材质,Complex Lit着色器适用于模拟需要更复杂光照的高级材质,例如透明图层。Simple Lit着色器可以将内置RP制作的非PBR项目转化为URP,该着色器是非PBR的,不被Shader Graph支持。Baked Lit着色器用于简单全局光照或烘焙光照的条件下,此时不需要实时光照。
SRP Batcher相容性:为确保着色器与SRP Batcher相容:① 在单个名为UnityPerMaterial的CBUFFER中声明所有的材质性质;② 在单个名为UnityPerDraw的CBUFFER中声明所有的内置引擎性质,例如unity_ObjectToWorld或unity_WorldTransformParams。(详见:Unity - Manual: Scriptable Render Pipeline Batcher)
4.8.1、着色模型
一个着色模型(Shading Model)定义了材质颜色的变化,基于如下因素:表面取向(surface orientation)、观察方向和光照。着色模型的选择基于艺术风格和性能预算。URP提供了如下的着色模型:Physically Based Shading (PBS)、Simple Shading、Baked Lit Shading和No lighting。
4.8.1.1、Physically Based Shading
基于物理着色(Physically Based Shading, PBS)基于物理定律,通过计算表面反射的光量来模拟对象在真实世界的外观,可以创建出照片般逼真的物体和表面。PBS模型遵守以下两条定律:① 能量守恒,表面的反射光不会超过入射光,除非该物体发光,如霓虹灯;② 微观几何形态(Microgeometry),物体表面具有微观尺度的几何形状,光滑的微观几何形状使之看起来像镜子,粗糙的微观几何形状使之看起来更加暗淡。(在URP中可以模拟被渲染对象表面的光滑度)(该模型不适用于低端移动设备,改用Sample Shading模型的着色器)
光打到一个物体表面时,部分光反射,部分光折射。反射光被称为镜面反射(specular reflection)。根据摄像机方向和光的入射角,表现不同。在该模型中,镜面反射的高光由GGX函数模拟(一种用于计算光照模型中镜面反射分量的函数,高光更亮更真实)。对于金属物体,表面吸收并改变光线。对于非金属物体,或叫绝缘体,表面反射部分光。
使用PBS的URP着色器:Lit、Particles Lit。
4.8.1.2、Simple Shading
Simple Shading模型基于Blinn-Phong模型。在该模型下,材质反射漫反射光和镜面反射光,且这两者间没有联系,只取决于材质的性质,因此反射光可能会超过入射光。镜面反射只与摄像机方向有关。(该模型适用于风格化视觉效果或者能力弱的平台。在该模型下,材质不是完全像照片一样真实,着色器也不保留能量。)
使用Simple Shading的URP着色器 :Simple Lit、Particles Simple Lit 。
4.8.1.3、Baked Lit Shading
Baked Lit Shading模型中,材质接收来自Lightmaps和Light Probes的烘焙光线,仅用很小的性能成本就位Scene增加了景深。(Baked Lit Shading模型没有实时光照,游戏可以在低端平台上运行。)
使用Baked Lit Shading模型的URP着色器:Baked Lit。
4.8.1.4、No lighting
某些着色器是不亮的,即没有平行光和烘焙光。由于没有光源计算,这些着色器的编译比带光照的着色器更快。如果提前知道游戏对象或视野不需要光照,选择无光照Unlit着色器可以节省计算和构建时间。
使用No Lighting着色器的URP着色器:Unlit、Particles Unlit。
4.8.2、Complex Lit
Complex Lit着色器包含Lit着色器的所有功能,并增加了高级材质特性,其中某些特性资源需求高并且要求Shader Model 4.5硬件。在延迟渲染路径中,URP渲染用Complex Lit着色器的对象使用前向渲染路径。若硬件平台不支持Complex Lit着色器的特性,将改用Lit着色器。
使用Complex Lit着色器:① 在项目中创建一个要用Complex Lit着色器的材质;② 在该材质的Inspector中,在Shader属性中选择Universal Render Pipeline-> Complex Lit。
材质的Inspector主要含4个部分:Surface Options、Surface Inputs、Detail Inputs、Advanced Options。
4.8.2.1、Surface Options
控制URP渲染材质的方式。
Workflow Mode | 选择适合Texture的工作流,分为Metallic和Specular。 |
Surface Type | 选择材质的表面类型,分为不透明Opaque和透明Transparent,决定了URP的渲染通道。不透明表面一直可见,URP先渲染不透明材质。透明表面受其背景影响,外观受选择的透明表面类型影响,URP在不透明对象后用独立通道渲染透明材质。 |
Blending Mode | 定义通过混合背景像素来计算透明材质的每个像素颜色的方法(只在选择Transparent的表面类型后可见)。 Alpha:使用材质的Alpha值来改变一个对象的透明程度,0是完全透明,1是完全不透明但让在透明渲染通道,可以用于类似云的效果(完全不透明但随时间褪色)。 Premultiply:与Alpha效果类似,但保留了反射、高光。仅反射光可见,例如透明玻璃。 Additive:在材质的表面之上添加额外一层,类似全息图的效果。 Multiply:将材质的颜色与表面之后颜色相乘,营造更暗的效果,类似透过彩色玻璃看。 |
Render Face | 决定渲染几何体的哪些边。 Font Face:渲染几何体的前面,剔除背面。(默认设置) Back Face:渲染几何体的背面,剔除前面。 Both:渲染几何体前面、背面,有助于想要两面都可见的小的、平的物体,例如树叶。 |
Alpha Clipping | 效果类似Cutout着色器(在透明和不透明的厚边界创建透明效果,且只有完全透明和完全不透明的区域,可以透明度来创建材质的形状,例如树叶、有洞的衣服、透明头盔)。为实现该效果,URP不渲染低于Threshold门限的Alpha,低于门限的是完全透明的,高于门限的是不透明的,默认值为0.5。 |
Receive Shadows | 勾选后,物体将在其他物体上投射阴影。不勾选,物体将没有阴影。 |
4.8.2.2、Surface Inputs
Surface Inputs描述表面本身,使表面看起来湿、干、粗糙或光滑。(若使用内置RP的标准着色器,这些选项与Material Editor中的Main Maps设置类似。)
Base Map | 为表面添加颜色,也称漫反射贴图。点击对象选择器为其分配Texture,或者用颜色选择器 指定Texture顶部的色调(点击色板可以分配另一种色调)。(若在Surface Options中选择了Transparent或Alphabet Clipping,材质将使用Texture的alpha通道或颜色。) |
Metallic/ Specular Map | 为Surface Options中的选择Workflow Mode指定一个贴图。 对于Metallic贴图工作流,贴图的颜色由上述Base Map中获取。通过滑块来调节表面的金属感metallic,1是完全金属感,例如银、铜,0是完全绝缘体,例如塑料、木材,0~1可以表示有污渍的金属表面。 对于Specular贴图工作流,用对象选择器来分配贴图,或者用颜色选择器。 Smoothness:对上述两种工作流,都可以用光滑度滑块来调节表面的高光分布,0是宽且粗糙的高光,1是窄且锐利的高光(类似玻璃),0~1是半光泽,例如0.5表示类似塑料光泽。 Source:选择着色器对光滑度贴图的采样位置。Metallic Alpha(默认值)是Metallic贴图的alpha通道,Albedo Alpha是Base贴图的alpha通道。若选定的Source有alpha通道,着色器将对通道进行采样,并乘以Smoothness值。 |
Normal Map | 为表面添加法线贴图Normal Map(凹凸映射bump mapping),可以为表面添加细节,例如凹凸、划痕和凹槽。通过对象选择器添加法线贴图,法线贴图拾取环境中的环境光ambient lighting。旁边的数值是一个影响法线贴图效果的乘数,较小的值将减弱其效果。 |
Height Map | 为表面添加高度贴图Height Map(视差映射parallax mapping)比法线贴图更进一步实现表面级的遮挡效果,以灰度表示高低,近处的凸起将膨胀,远处的凸起将被遮挡,也更消耗资源。通过对象选择器添加高度贴图。旁边的数值是一个影响高度贴图效果的乘数,较小的值将减弱其效果。 |
Occlusion Map | 为表面添加遮挡贴图Occlusion Map。通过模拟环境光和反射光产生的阴影来使光线看起来更加真实,例如光照不到的角落、物体的裂纹。通过对象选择器添加遮挡贴图。(遮挡贴图一般是通过3D软件模拟得到的。) |
Clear Coat | 勾选时,启用Clear Coat特性。该特性在原材质之上添加一层额外的材质,来模拟物体上的透明薄膜。该特性轻微影响位于下层的原材质的颜色和Smoothness值。Clear Coat的折射率IOR是1.5。 Performance Impact:由于每层都进行一次光照评估,Clear Coat的成本大约是原材质的2倍。 Mask:效果的强度,0是没影响(并不会关掉特性),1是最大影响。 Smoothness:调节表面的高光分布,0是宽且糙的高光,1是窄且锐利的高光(类似玻璃)。 (Mask属性左侧有Clear Coat贴图属性,具有如下映射关系:Red-Mask属性,Green-Smoothne属性。如果存在Clear Coat贴图,URP会将贴图的像素乘上Mask属性的值。) |
Emission | 勾选时,实现表面发光的效果。 Emission Map:使用对象选择器分配一个Emission贴图,从Assets中选择一个纹理。 Emission Color:使用颜色选择器在物体的颜色之上分配一个色调,实现诸如熔岩的效果,白色超过100%,可以比白色更闪亮但不是白色。 (若未分配Emission贴图,Emission将只使用Emission Color中的色调;若未启用Emission,URP将发光设为黑色并且不计算。) |
Tiling | 用于根据U和V轴放缩纹理以适应网格的一个2D乘数值,有助于实现地板、墙壁等表面。默认值为1,即没有放缩。大于1的值,将使纹理在网格中重复;小于1的值将拉伸纹理。 |
Offset | 用于在网格上定位纹理的2D偏移,在U和V轴上调整纹理的位置。 |
4.8.2.3、Detail Inputs
为表面添加额外的细节。(GPU要支持着色器模型2.5及以上)
Mask | 选定一个纹理来定义区域,在该区域上用Detail Inputs贴图覆盖Surface Inputs贴图。使用选定纹理的alpha通道,Tiling和Offset设置对蒙版无效。 |
Base Map | 选定包含表面细节的纹理,该贴图使用重叠模式与Surface Inputs的Base Map混合。 |
Normal Map | 选定包含法向量数据的纹理,使用法线贴图创建诸如凹凸、划痕和凹槽的表面细节。通过滑块可以调节该贴图的效果强度,默认值为1。 |
Tiling | 在网格上沿着U和V轴放缩Base Map和Normal Map,使之适应网格,默认值为1,大于1的值,将使纹理在网格中重复;小于1的值将拉伸纹理。 |
Offset | 沿着U和V轴移动Base Map和Normal Map。 |
4.8.2.4、Advanced Options
控制渲染的基本计算,对表面没有可见的影响。
Specular Highlights | 启用后,使材质具有来自直接照明(Directional、Point、Spot)的镜面高光,即材质表面将反射这些光源的光。禁用时(默认),将省去高光计算,使着色器渲染更快。 |
Environmental Reflections | 启用后,若有光照探针Light Probes时,使用光照探针;若没有,则使用反射探针。禁用时,表面将没有反射,着色器计算更少。 |
Enable GPU Instancing | 启用后,若硬件支持或者网格中使用相同的材质,将批量渲染具有相同几何体或材质的网格。 |
Priority | 通过滑块定义材质的时间顺序渲染的次序,优先渲染较小值的材质。可以通过条件该属性使管线优先渲染某个靠前的材质,不用在重叠位置渲染两次,以此来减少过度绘制。该功能类似于内置RP的渲染队列render queue。 |
4.8.2.5、Channel Packing
该着色器使用通道打包Channel Packing,可以将RGBA纹理用在金属光泽、光滑度、闭塞性质上。当使用纹理打包(texture packing)时,只需要加载一个纹理进内存,而不是单独三个纹理。将纹理贴图写入Substance或Photoshop等软件时,可以这样打包纹理贴图:
通道Channel | 性质Property |
Red | Metallic |
Green | Occlusion |
Blue | None |
Alpha | Smoothness |
通道Channel | 性质Property |
Red | Mask |
Green | Smoothness |
Blue | None |
Alpha | None |
注:通道打包Channel Packing:将不同的灰度图用在纹理图像的每个通道中,红、绿、蓝和Alpha。这几个通道都是用灰度图来代表传统的RGB颜色数据,因此也可以存储不同类型的图像数据。着色器可以提取独立的通道用于特定的效果,例如,红通道用于发光、绿通道用于镜面反射、蓝通道用于sound type、alpha通道用于物理信息等。每个通过可能有完全不同的布局,因此使用不同的UVs(纹理坐标Texture Coordinate,存储在网格顶点中的数对)。在游戏制作中,该技术可以避免加载不同的灰度图像,可以节约内存,然而会提高着色器的复杂度,增加drawcall(将几何体和纹理信息发送到GPU,单个模型若使用多个纹理、着色器,可能发生多次drawcall)。RMA是一种包含了粗糙度Roughness、金属光泽Metallic、环境光闭塞Ambient occlusion的打包贴图,一般用于基于物理的渲染PBR。
4.8.3、Lit
Lit着色器能够以照片般真实地模拟现实世界的石头、木材、玻璃、塑料和金属等表面。光照和反光都栩栩如生,在不同的光照条件下都做出正确的反应,例如明亮的阳光下或是黑暗的洞穴中。Lit着色器使用了URP中计算量最大的着色器模型。
使用Lit着色器:① 在项目中创建一个要用Lit着色器的材质;② 在该材质的Inspector中,在Shader属性中选择Universal Render Pipeline-> Lit。
Lit着色器的Inspector的UI界面与Complex Lit一致(Surface Inputs中没有Clear Coat)。
4.8.4、Sample Lit
Sample Lit着色器用于性能比真实感更重要的情况,其对光照的进行了简单的估计,使用的Sample Lit模型不考虑物理规律和能量守恒,渲染更快。
使用Sample Lit着色器:① 在项目中创建一个要用Sample Lit着色器的材质;② 在该材质的Inspector中,在Shader属性中选择Universal Render Pipeline-> Sample Lit。
Sample Lit着色器的Inspector的UI界面与Complex Lit一致(Surface Options中没有Workflow Mode和Receive Shadows;Surface Inputs中没有Height Map、Occlusion Map和Clear Coat;没有Detail Inputs;Advanced中没有Environment Reflections)。
4.8.5、Baked Lit
Baked Lit着色器一般用于只需要通过光照贴图和Light Probes产生烘焙光照的风格化游戏,不使用基于物理的着色模型,且没有实时光照,因此,所有实时相关的着色器关键字和变量都会从着色器代码中剔除,使计算更快。
使用Baked Lit着色器:① 在项目中创建一个要用Baked Lit着色器的材质;② 在该材质的Inspector中,在Shader属性中选择Universal Render Pipeline-> Baked Lit。
Baked Lit着色器的Inspector的UI界面与Complex Lit一致(Surface Options中没有Workflow Mode和Receive Shadows;Surface Inputs中没有Metallic/Specular Map、Height Map、Occlusion Map、Clear Coat和Emission;没有Detail Inputs;Advanced中没有Specular Heighlights和Environment Reflections)。没有Channel Packing。
4.8.6、Unlit
Unlit着色器用于项目中不需要光照的特性或特定对象,使用最简单的着色模型,没有耗时的计算或查找,可用于低端硬件。
使用Unlit着色器:① 在项目中创建一个要用Unlit着色器的材质;② 在该材质的Inspector中,在Shader属性中选择Universal Render Pipeline-> Unlit。
Baked Lit着色器的Inspector的UI界面与Complex Lit一致(Surface Options中没有Workflow Mode和Receive Shadows;Surface Inputs中没有Metallic/Specular Map、Normal Map、Height Map、Occlusion Map、Clear Coat和Emission;没有Detail Inputs;Advanced中没有Specular Heighlights和Environment Reflections)。没有Channel Packing。
4.8.7、Terrain Lit
Terrain Lit地形着色器一把用于Unity中的Terrain,是Lit着色器的简单版本。一个Terrain可以使用至多8个地形层Terrain Layers的Terrain Lit材质。
Terrain Lit材质的性质:
Enable Height-based Blend | 启用后,可使Unity从Mask Map纹理的蓝通道中获取高度值。 若禁用,Unity将基于在splatmap纹理中绘制的权重混合地形层。若禁用此特性并且将Terrain Lit着色器材质指定给Terrain,则URP会在Paint Texture Tool Inspector中为添加到该Terrain的每个地形层添加一个附加选项Opacity as Density Blend。 (若一个Terrain上有超过4个地形层,Unity将忽略该选项。) |
Height Transition | 选择地形层间平滑转变区的大小(以世界单位)。 |
Enable Per-pixel Normal | 启用后,Unity以像素级对法线贴图纹理进行取样,为远处的地形保留更多几何细节。Unity在运行时,从高度贴图生成一个几何法线贴图。而不是从网格几何体。这意味着可以获得高分辨率的网格法线,即使网格的分辨率不高。 (只有在Terrain启用Draw Instanced后生效。) |
创建Terrain Lit材质:创建一个与Terrain对象兼容的材质:① 创建一个新材质,Assets-> Create-> Material;② 在该材质的Inspector中,在Shader属性中选择Universal Render Pipeline-> Terrain-> Lit。
将Terrain Lit材质分配给Terrain对象:① 选择一个Terrain对象,点击设置按钮,打开Terrain Settings部分;② 在Material属性中,选择一个TerrainLit材质,可以用对象选择器或直接拖动。
使用Paint Holes工具:确保在项目的URP Asset中,Terrain Holes勾选框被勾选,否则创建应用时,Terrain洞会不见了。
注:地形层Terrain Layer是定义Terrain表面品质的Asset。一个地形层包含了纹理,以及地形材质用于渲染Terrain表面的其他性质。由于地形层是Asset,可以在其他Terrain网格中复用。
4.8.8、Particles Lit
Particles Lit着色器可以颗粒表现出真实感,例如营火粒子、雨滴或是火炬的烟。该着色器使用了计算量最大的着色模型,可能会影响性能。
使用Particles Lit着色器:① 在项目中创建一个要用Particles Lit着色器的材质;② 在该材质的Inspector中,在Shader属性中选择Universal Render Pipeline-> Particles-> Lit。
Particles Lit着色器的Inspector的UI界面与Complex Lit一致(Surface Options中没有Workflow Mode和Receive Shadows,多了Color Mode;Surface Inputs中没有Height Map、Occlusion Map、Clear Coat、Tiling和Offset;没有Detail Inputs;Advanced中没有Specular Heighlights、Environment Reflections和Enable GPU Instancing,多了Flip-Book Blending和Vertex Streams)。没有Channel Packing。
Surface Options:
Color Mode | 下拉框选择颗粒颜色与材质颜色的混合模式。 Multiply:将两种颜色相乘获得一个更暗的颜色。 Additive:将两种颜色相加获得一个更亮的颜色。 Subtractive:将颗粒颜色从材质的基色中减去,使像素的亮度变低。 Overlay:将颗粒颜色混合在材质的基色之上,值大于0.5时颜色更亮,小于0.5时更暗。 Color:使用颗粒颜色为材质上色,同时保持材质基色的值和饱和度。有利于为单色场景添加颜色飞溅的效果。 Difference:返回两种颜色的值的不同,有利于混合颗粒和材质颜色相近的情况。 |
Advanced:影响后台渲染,没有可见效果,但对渲染计算有影响。
Flip-Book Blending | 启用后,将翻书帧(flip-book frames)一起混合。在具有有限帧的纹理动画中很有用,使动画更平滑,但会降低性能。 |
Vertex Streams | 此列表显示此材质正常工作所需的顶点流。若顶点流分配不正确,将显示Fix Now按钮。点击修复按钮后,将对该材质所分配的粒子系统应用其正确的顶点流设置。 |
透明表面类型:在Surface Options中选择Transparent后,该选项出现。
Soft Particles | 启用后,使粒子在接近了景深缓存的其他几何体的表面相交处后淡出。Surface Fade选项: Near:粒子完全透明的位置到另一表面的距离。粒子完全淡出的地方。 Far:粒子完全不透明的位置到另一表面的距离。粒子表现出固体的地方。 (距离用世界单位表示。)(该设置使用URP创建的CameraDepthTexture。使用前须启用URP Assets或该粒子使用的摄像机中的Depth Texture。) |
Camera Fading | 启用后,使粒子接近摄像机后淡出。Distance选项: Near:粒子完全透明的位置到摄像机的距离。粒子完全淡出的地方。 Far:粒子完全不透明的位置到摄像机的距离。粒子表现出固体的地方。 (距离用世界单位表示。)(该设置使用URP创建的CameraDepthTexture。使用前须启用URP Assets或该粒子使用的摄像机中的Depth Texture。) |
Distortion | 通过使粒子与其前方的对象进行折射来创建扭曲效果,有利于创建热浪效果、扭曲粒子后方的对象。 Strength:控制粒子使背景扭曲的程度,正值与负值效果相反,若正值向右偏移,那负值就向左偏移。 Blend:控制扭曲的可见程度。0代表扭曲不可见,1代表只有扭曲效果可见。 (该设置使用URP创建的CameraDepthTexture。使用前须启用URP Assets或该粒子使用的摄像机中的Depth Texture。) |
4.8.9、Particles Simple Lit
Particles Sample Lit着色器更注重性能而不是真实感,对光照进行粗略估计,不遵守物理定律或是能量守恒。与Simple Lit着色器类似。
使用Particles Sample Lit着色器:① 在项目中创建一个要用Particles Sample Lit着色器的材质;② 在该材质的Inspector中,在Shader属性中选择Universal Render Pipeline-> Particles-> Sample Lit。
Particles Sample Lit着色器的Inspector的UI界面与Particles Lit一致(Surface Inputs中没有Metallic Map,多了Specular Map;Advanced中多了Specular Highlights)。
Advanced:
Specular Highlights | 启用后,粒子将产生来自直接照明(Directional、Point、Spot)的镜面高光,即每个粒子都会反射这些光源来发光。禁用后,着色器将剔除高光计算,使渲染更快。 |
4.8.10、Particles Unlit
Particles Unlit着色器不需要光照,没有光照计算或查找的耗时,适用于低端硬件。类似于Unlit着色器。
使用Particles Unlit着色器:① 在项目中创建一个要用Particles Sample Lit着色器的材质;② 在该材质的Inspector中,在Shader属性中选择Universal Render Pipeline-> Particles-> Unlit。
Particles Unlit着色器的Inspector的UI界面与Particles Lit一致(Surface Inputs中没有Metallic Map)。
4.8.11、Decal
若一个材质使用材质类型为Decal的着色器图形Shader Graph,Decal Projector组件可以将该材质投影成贴花Decal。可以直接将使用Decal着色器图形的材质分配给一个游戏对象。
Decal着色器的Inspector的UI界面只有Inputs和Advanced两部分。
Inputs:
Base Map | 材质的基本纹理。 |
Normal Map | 材质的法线纹理。 |
Normal Blend | 定义在Normal Map中选择的法线纹理与贴花投影到的材质的法线贴图的混合比例。0:贴花不影响其投影到的材质;1:贴花的法线贴图将替换其投影到材质的法线贴图。 |
Advanced:分配了材质类型为Decal的着色器图形的材质才具有该性质。
Enable GPU Instancing | 同上。具有相同几何体和材质的网格在同一批渲染。 |
Priority | 同上。决定材质渲染的时序,值越低越先渲染。 |
Mesh Bias Type | 网格偏置类型。可以防止贴花游戏对象与其重叠的游戏对象之间发生z-fighting(深度冲突,场景中两个模型在同一个像素的渲染结果对应到相同的深度值产生的,重叠部位不停闪烁的现象)。此属性仅适用于直接分配了材质类型为贴花的材质的游戏对象。 View Bias:世界空间偏置(单位为米)。绘制贴花游戏对象时,Unity会沿视角向量将游戏对象的每个像素移动该值。正值会将像素移动到更靠近摄影机的位置,即Unity将在重叠网格的上部绘制贴花游戏对象,从而防止z-fighting。Decal Projector忽略此特性。 Depth Bias:当绘制贴花游戏对象时,Unity根据该值改变每个像素的深度值。负值表示像素靠近摄像机,因此Unity会将Decal对象绘制在重叠的网格Mesh上,可以避免Z-fighting。Decal Projector忽略此特性。 |
4.8.12、Shader Stripping着色器剥离
URP中的着色器使用着色器关键字Shader Keywords来支持不同的特性,即Unity编译了许多着色器变体Shader Variants。若禁用了URP Asset中的某个特性,URP将自动剥离相关的着色器变体,这有助于加速构建、节约内存和减小文件尺寸。
在Editor/ShaderPreprocessor.cs文件中,可以查看URP关于着色器剥离的代码。
4.8.12.1、剥离特性着色器变体
Unity会默认编译启用的着色器变体和禁用的变体。为了减少变体的数量,可以在URP全局设置中启用Strip Unused Variants,然后进行以下操作:首先,在所有的URP Assets中禁用一个特性,URP只保留禁用该特性的变体;其次,在所有的URP Assets中启用一个特性,URP只保留启用该特性的变体。(若禁用了Strip Unused Variants,Unity将不会剥离特性被禁用的变体。)
剥离一个特性:先要在构建中的所有URP Assets中禁用某个特性,才能剥离该特性相关的着色器变体。构建中的URP Assets包括:① 在Graphics Settings中设为默认渲染管线资源的URP Asset;② 在为当前构建目标启用的一个Quality Settings等级中设为渲染管线资源的任意URP Assets。(避免在构建中包含使用不同渲染路径的URP Assets,因为这会导致Unity为每个关键字创建两组变体。)Shader Stripping | Universal RP | 12.1.12 (unity.cn)
特性 | 如何禁用 | 对应的关键字 | 渲染路径 |
Accurate G-buffer normals | 在URP Assets中禁用Accurate G-buffer normals。对使用Vulkan图形API的平台没影响。 | _GBUFFER_NORMALS_OCT | 延迟 |
Additional lights | 在URP Assets中的Lighting部分,禁用Additional Lights | _ADDITIONAL_LIGHTS,_ADDITIONAL_LIGHTS_VERTEX | 前向 |
Ambient occlusion | 在URP Assets使用的所有渲染器中移除Ambient occlusion渲染特性 | _SCREEN_SPACE_OCCLUSION | 前向、 延迟 |
Decals | 在URP Assets使用的所有渲染器中移除Decals渲染特性 | _DBUFFER_MRT1, _DBUFFER_MRT2, _DBUFFER_MRT3, _DECAL_NORMAL_BLEND_LOW, _DECAL_NORMAL_BLEND_MEDIUM, _DECAL_NORMAL_BLEND_HIGH, _DECAL_LAYERS | 前向、 延迟 |
Fast sRGB to linear conversion | 在URP Assets中的Processing部分,禁用Fast sRGB/linear conversions | _USE_FAST_SRGB_LINEAR_CONVERSION | 前向、 延迟 |
Holes in terrain | 在URP Assets中的Rendering部分,禁用Terrain Holes | _ALPHATEST_ON | 前向 |
Light cookies | 在项目中的所有光源中移除Cookie textures(Cookies) | _LIGHT_COOKIES | 前向、 延迟 |
Light layers | 禁用Light Layer | _LIGHT_LAYERS | 前向、 延迟 |
Reflection Probe blending | 禁用Probe Blending | _REFLECTION_PROBE_BLENDING | 前向、 延迟 |
Reflection Probe box projection | 禁用Box Projection | _REFLECTION_PROBE_BOX_PROJECTION | 前向、 延迟 |
Render Pass | 在URP Assets使用的所有渲染器中禁用Native Render | _RENDER_PASS_ENABLED | 前向、 延迟 |
Shadows from additional lights | 在URP Assets中的Additional Light部分,禁用Cast Shadows | _ADDITIONAL_LIGHT_SHADOWS | 前向、 延迟 |
Shadows from the main light | 在URP Assets中的Main Light部分,禁用Cast Shadows。移除的关键字取决于个人设置。 | _MAIN_LIGHT_SHADOWS, _MAIN_LIGHT_SHADOWS_CASCADE, _MAIN_LIGHT_SHADOWS_SCREEN | 前向、 延迟 |
Soft shadows | 在URP Assets中的Shadows部分,禁用Soft shadows | _SHADOWS_SOFT | 前向、 延迟 |
4.8.12.2、剥离后期处理着色器变体
在URP全局设置中启用Strip Unused Post Processing Variants,可以为Volume Overrides剥离不用的着色器变体。例如,项目中只使用了Bloom特效,URP将只保留Bloom变体并剥离其他的所有后期处理变体。
Unity在所有Scene中监测Volume Overrides,因此不能通过从构建中移除一个Scene但把它保留在项目中来剥离一个变体。
还应该在URP全局设置中启用Strip Screen Coord Overrides Variants,除非重写屏幕坐标以支持在大量多个显示器(簇显示屏)上的后期处理。
Volume Override | 对应的关键字 |
Bloom | _BLOOM_HQ, BLOOM_HQ_DIRT, _BLOOM_LQ, BLOOM_LQ_DIRT |
Chromatic Aberration | _CHROMATIC_ABERRATION |
Film Grain | _FILM_GRAIN |
HDR Grading | _HDR_GRADING |
Lens Distortion | _DISTORTION |
Tonemapping | _TONEMAP_ACES, _TONEMAP_NEUTRAL, _TONEMAP_GRADING |
4.8.13、编写自定义着色器
4.8.13.1、准备工作
创建一个简单的Scene:① 在现有项目中安装URP或者使用Universal Project Template创建项目;② 创建一个用于测试着色器的游戏对象,并创建一个新材质分配给该游戏对象;③ 创建一个新的着色器资源,并将其分配给新建的材质,打开着色器资源以修改着色器源文件。
4.8.13.2、Shader类基本概念
ShaderLab:Unity着色器是用Unity专用的ShaderLab语言编写,用Shader块定义一个着色器对象(Shader类的实例,打包了着色器程序、更改GPU设置的说明和使用方式信息)。一个着色器对象中一般包含Shader、Properties、SubShader、Pass和HLSLPROGRAM块。
Shader块:ShaderLab代码以Shader声明开始,例如Shader "Example/URPUnlitShaderX"。声明中的路径定义了着色器展示的名称,以及在Material的Shader属性中寻找着色器的位置。方法Shader.Find也使用该路径。
Properties块:包含了在Material的一些性质的声明,可以在其Inspector窗口上对这些性质进行设置。若完全使用脚本定义着色器的值,或不希望在Inspector中编辑材质性质,或无法作为材质的性质,则不需要编写Properties块。基本格式为:[attr] _Name("DispalyName", type) = defaultValue。(在HLSL代码中,必须将每种材质的变量放在相同的CBUFFER中,以实现SRP Batcher兼容性。)
SubShader块:用于将着色器对象分成兼容不同的硬件、渲染管线和运行设置的几个部分,包含该SubShader所兼容的硬件、渲染管线和运行设置的信息,以及ShaderLab tag标签(使用键值对提供信息,例如Tags { "RenderPipeline" = "UniversalPipeline" }意为该SubShader用于URP)和一个或多个Pass块。着色器源文件可以包含一个或多个SubShader块。
Pass块:着色器对象的基本元素,包含Pass标签(用键值对提供该Pass相关的渲染方式/时间信息)、运行着色器前更新GPU渲染状态的说明以及着色器程序(组织成一个或多个着色器变体)。也可以使用独立的多个Pass定义着色器中不同的工作部分,例如修改渲染状态、不同的着色器程序或者不同的LightMode标签等。一个Pass块中包含名称Name(例如:Name "ExamplePass")、标签Tag(LightMode标签用于所有的渲染管线,其他标签会因渲染管线变化,例如:Tags { "LightMode" = "Always" })、执行命令commands(分为三类:设置GPU渲染状态、创建特殊用途Pass、不需要写HLSL的传统固定函数样式Legacy Functionality。例如:Blend One OneMinusSrcAlpha)。
类型 | 命令 | 功能 |
设置渲染状态 | AlphaToMask | 开关GPU的Alpha-to-coverage模式,该模式通过将多重采样的覆盖遮罩比例修改为片段着色器fragment shader输出结果中的alpha值,可以在使用Alpha测试的着色器进行多重采样MSAA时,降低过多的锯齿。(使用MSAA时启用,否则。) AlphaToMask On。 |
Blend | 决定GPU将片段着色器的输出与渲染目标的alpha混合方式。可以使用BlendOp命令设置混合操作,来决定该命令的功能(可能支持受限)。启用后,会禁用GPU上的一些优化,从而导致GPU帧时间增加。(可以改变渲染状态,在Pass中改变该Pass的状态,在SubShader块中修改其中所有的Pass的状态。) 混合公式为:finalValue = source Factor * source Value operation destination Factor * destinationValue。 Factor的值有One、Zero、SrcColor、OneMinusDstAlpha等,分别代表1、0、源颜色值、1-目标alpha值。 Blend SrcAlpha OneMinusSrcAlpha代表传统透明。 | |
BlendOp | Blend命令使用的混合操作(在同一个Pass或SubShader中,须有Blend命令,才会生效)(可能支持受限)。 混合方式有Add、Sub、RevSub、Min、Max等。 BlendOp Sub。 | |
ColorMask | 设置颜色通道写入遮罩,防止GPU写入渲染目标中的通道。默认情况下,GPU写入所有的RGBA通道,但某些特效可能会留下某个通道不修改,例如禁用颜色渲染来渲染无色的阴影。 通道有0、R、G、B、A或组合,如RB、RGB。 ColorMask RGB。 | |
Conservative | 保守光栅化conservative rasterization。光栅化是通过计算几何体上的三角形来生成图像的渲染技术,根据像素是否被三角形有效覆盖,从而将向量数据转化为像素数据。保守光栅化是指一个像素只需要部分被三角形覆盖,有利于碰撞监测、遮挡剔除、可见性监测等确定性情况。启用后,会增加GPU帧时间。 Conservative Off。 | |
Cull | GPU剔除多边形,基于多边形相对于摄像机所面对的方向。剔除过程决定了哪些不绘制,不用浪费时间渲染在最终图像中看不见的东西,提高渲染效率。 剔除模式:Back、Front和Off,分别表示剔除背离摄像机的多边形(默认值)、剔除面向摄像机的几何体(将几何体由内向外翻转)、不剔除(用于透明对象或双层墙壁)。 Cull Back。 | |
Offset | GPU的深度偏移。深度偏移是决定绘制几何体深度(与摄像机的距离)的GPU设置,调整深度将强制GPU将两个相同深度的几何体绘制成一上一下不重叠,可以避免Z-fighting或阴影失真acne。 Offset <factor>, <units>。Offset 1, -1。 factor:-1~1。放缩最大Z坡度/深度坡度来为每个多边形产生可变的深度偏移,不与近/远裁剪面平行的多边形具有Z坡度,调整该值来避免视觉瑕疵。 units:-1~1。放缩最小可解析深度缓存值来产生深度偏移常数。负值靠近摄像机。 | |
Stencil | 配置模板测试stencil test并写入GPU模板缓存。模板缓存是在帧缓存中为每个像素存储的8bit整数值。模板测试是在为给定像素执行片段着色器前,将把其模板缓存中的现有值与给定参考值比较。若模板测试通过,GPU继续深度测试;若不通过,GPU不再处理该像素。即使用模板缓存来决定像素是否绘制。一般用于入口大门、镜像或硬阴影等效果,也可以创建一个其他着色器对象无法绘制的屏幕遮罩,即其他着色器执行模板测试的结果永远不通过Never。 Stencil { Ref 2 Comp Always Pass Replace } 配置模板测试:Ref、ReadMask、Comp。 控制写入模板缓存:Ref、WriteMask、Pass、Fail、ZFail。 | |
ZClip | 深度裁剪模式,决定GPU处理在近裁剪面和远裁剪面之外的片段的方式。将GPU深度裁剪模式设为紧逼,有助于模板阴影渲染,不需要对远裁剪面之外的几何体进行特殊处理,减少了渲染操作,但是会导致错误的Z排序。 ZClip False。(比近裁剪面更近的片段就在近裁剪面上,比远裁剪面更远的同样) | |
ZTest | 深度测试模式,设置深度测试通过或失败的条件。允许具有Early-Z功能的GPU在渲染管线前期(在片段着色器之前)就剔除几何体,确保正确的几何体排序。 测试结果有:Less、Equal、GEqual、Always等,分别代表只绘制现存几何体之前的几何体、只绘制相同距离的、只绘制相同距离或之后的、绘制所有几何体/不进行深度测试。 ZTest Greater。 | |
ZWrite | 深度缓存写入模式,设置是否在渲染期间更新深度缓存。通常,ZWrite对不透明对象启用,对半透明对象禁用。禁用ZWrite会导致错误的深度排序,需要在GPU中进行几何体排序。 ZWrite Off。 | |
通道命令 | UsePass | 定义一个Pass,从另一个着色器对象中导入一个已经命名的Pass的内容。可以减少着色器源文件的代码重复。 UsePass "着色器路径/Pass名称"。 |
GrabPass | 创建一个抓取屏幕内容(从帧缓存frame buffer中)到纹理中的一个Pass,以便用于后续Pass。该命令会显著增加CPU和GPU的帧时间,尽量不要使用。 GrabPass{}:用于同一个SubShader中的后续Pass,渲染包含该命令的批次时都会抓取屏幕(一帧可能抓取多次)。引用的纹理名为_GrabTexture。 GrabPass{ "GivenName" }:用于同一帧的后续Pass,可以是多个SubShader。引用的纹理名为给定的名字。 |
HLSLPROGRAM块:该部分包含HLSL程序代码,以HLSLPROGRAM开头,以ENDHLSL结尾。HLSL语言是URP着色器最适用的语言。URP也支持CG语言,在着色器中以CGPROGRAM开头,以ENDCGPROGRAM结尾,但与SRP不是很兼容。#include声明代表引用Core.hlsl文件,该文件包含常用的HLSL宏和函数的定义,也包含其他HLSL文件的引用。
Pass{
HLSLPROGRAM // HLSL代码块,SRP使用HLSL语言
...
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" // HLSL文件
struct Varyings { float4 positionHCS : SV_POSITION; };
Varyings vert(Attributes IN){
Varyings OUT;
OUT.positionHCS = TransformObjectToHClip(IN.positionOS.xyz); // 使用SpaceTransforms.hlsl文件中的函数
return OUT;}
...
ENDHLSL
}
4.8.13.3、编写着色器实例
UPR Unlit基本着色器代码:该着色器将着色器中预定义的颜色填充进Mesh。
Shader "Example/URPUnlitShaderX"
{
Properties{}
SubShader
{ // Tag定义了SubShader何时/何种情况下执行
Tags { "RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline" }
Pass
{
HLSLPROGRAM
#pragma vertex vert // 定义顶点着色器的名称
#pragma fragment frag // 定义片段着色器的名称
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" // 引用hlsl文件
struct Attributes
{ // positionOS变量包含了对象中的顶点坐标
float4 positionOS : POSITION;
};
struct Varyings
{ // 该结构体中的位置必须有SV_POSITION语义
float4 positionHCS : SV_POSITION;
};
// 顶点着色器的定义
Varyings vert(Attributes IN)
{
Varyings OUT;
OUT.positionHCS = TransformObjectToHClip(IN.positionOS.xyz); // 该函数将顶点位置从对象空间转换为齐次裁剪空间,来获取像素的位置
return OUT;
}
// 片段着色器的定义
half4 frag() : SV_Target
{
half4 customColor = half4(0.5, 0, 0, 1); // 定义颜色变量并返回
return customColor;
}
ENDHLSL
}
}
}
增加Properties块可自定义颜色:① 在Properties块中增加_BaseColor的定义,在材质的Inspector中将出现名为Base Color的属性。② 在Properties块中声明的性质,在HLSL中也需要声明。为保证着色器与SRP Batcher的兼容,需要将所有的材质属性声明在名为UnityPerMaterial的CBUFFER块中。③ 将片段着色器的返回值改为定义好的_BaseColor。
(SRP Batcher是显著提高使用SRP的应用性能的draw call优化机制,减少了为使用相同着色器变体的材质准备和调用draw call所需的CPU时间。)
(draw call是Unity发送给图形API来将几何体绘制在屏幕上的命令,告诉图形API何时以及如何绘制。每个draw call包含了图形API绘制图像所需的全部信息,例如纹理、着色器和缓存的信息。draw call的准备过程比其本身更耗费资源。优化draw calls)
Shader "Example/URPUnlitShaderXColored" { // 对本节4.8.13.3上方代码进行修改
Properties { // ①[attribute] _Name("DisplayName", type) = defaultValue
[MainColor] _BaseColor("Base Color", Color) = (1, 1, 1, 1)
}
SubShader {
Tags {...}
Pass {
...
// ②同时需要在HLSL中声明Properties块中声明的属性
CBUFFER_START(UnityPerMaterial) // 为保证与SRP Batcher兼容,以CBUFFER块声明
half4 _BaseColor;
CBUFFER_END
// ③片段着色器返回_BaseColor
half4 frag() : SV_Target
{
return _BaseColor;
}
}
}
}
4.8.13.4、绘制纹理
着色器绘制纹理:① 在Properties块中增加_BaseMap属性的定义,在材质的Inspector中将出现名为Base Map的属性,同时会自动添加Tilling和Offset操作。② 在结构体Attribute是和Varings中添加变量uv作为纹理的UV坐标。③ 将纹理定义为2D纹理,并为其制定一个采样器sampler。④ 为了使Tilling和Offset属性生效,在CBUFFER块中以_ST后缀声明纹理的性质(添加_ST后缀为了与一些宏兼容)。⑤ 为了使Tilling和Offset的值应用到变换Transformation,在顶点着色器中使用TRANSFORM_TEX宏进行变换。⑥ 在片段着色器中,使用SAMPLE_TEXTURE2D宏对纹理进行采样。
Shader "Example/URPUnlitShaderTexture" { // 对4.8.13.3中代码进行修改
Properties { // ①增加Base Map属性
[MainTexture] _BaseMap("Base Map", 2D) = "white" // 删除了BaseColor声明
}
SubShader {
Tags {...}
Pass {
...
struct Attributes
{
float4 positionOS : POSITION;
float2 uv : TEXCOORD0; // ②纹理的UV坐标
};
struct Varyings
{
float4 positionHCS : SV_POSITION;
float2 uv : TEXCOORD0; // ②纹理的UV坐标
};
// ③Texture2D和SAMPLER都是Core.hlsl中定义的宏
TEXTURE2D(_BaseMap); // 将纹理声明为Texture2D对象
SAMPLER(sampler_BaseMap); // 为_BaseMap指定采样器
// CBUFFER块
CBUFFER_START(UnityPerMaterial)
half4 _BaseColor;
float4 _BaseMap_ST; // ④以_ST后缀声明纹理_BaseMap
CBUFFER_END
Varyings vert(Attributes IN)
{
Varyings OUT;
OUT.positionHCS = TransformObjectToHClip(IN.positionOS.xyz);
// ⑤ TRANSFORM_TEX宏会执行Tilling和Offset的变换
OUT.uv = TRANSFORM_TEX(IN.uv, _BaseMap);
return OUT;
}
// ⑥SAMPLE_TEXTURE2D宏使用指定采样器对纹理进行采样
half4 frag(Varyings IN) : SV_Target
{
half4 color = SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, IN.uv);
return color;
}
}
}
}
4.8.13.5、可视化法向量
在Mesh上可视化法向量值:① 在作为顶点着色器的输入结构类型的Attributes结构体中,为每个顶点声明一个包含法向量的变量。② 在作为片段着色器的输入结构类型的Varyings结构体中,为每个片段声明一个用于存储法向量值的变量。③ 将法向量从对象转换到世界空间。④ 编辑片段着色器,使得在Mesh上渲染法向量值。法向量的值作为RGB颜色值,为了使RGB三个元素都为正,需要将法向量的(-1,1)范围变换为(0,1)。
Shader "Example/URPUnlitShaderNormalVector" { // 对4.8.13.3上方代码进行修改
Properties {}
SubShader {
Tags {...}
Pass {
...
// ①在顶点着色器的输入中为每个顶点声明法向量
struct Attributes
{
float4 positionOS : POSITION;
half3 normal : NORMAL; // 声明法向量
};
// ②在片段着色器的输入中为每个片段声明存储法向量的变量
struct Varyings
{
float4 positionHCS : SV_POSITION;
half3 normal : TEXCOORD0; // 三元法向量
};
// ③将法向量从对象转换到世界空间
Varyings vert(Attributes IN)
{
Varyings OUT;
OUT.positionHCS = TransformObjectToHClip(IN.positionOS.xyz);
OUT.normal = TransformObjectToWorldNormal(IN.normal); // TransformObjectToWorldNormal函数将对象坐标转换到世界空间
return OUT;
}
// ④通过片段着色器在mesh上渲染法向量的值
half4 frag(Varings IN) : SV_Target
{
half4 color = 0;
color.rgb = IN.normal * 0.5 + 0.5; // 三元法向量的数值作为RGB颜色值,同时保证RBG三个值都大于0
return color;
}
}
}
}
4.8.13.6、从深度纹理重建像素的世界空间坐标
本例中的Unity着色器使用深度纹理和屏幕空间UV坐标重建像素的世界空间位置,并在Mesh上绘制棋盘格图案以可视化位置。
准备工作:① 创建一个URP项目,并创建一个Scene;② 新建一个plane游戏对象,创建一个材质分配给plane,创建一个着色器分配给材质,修改着色器代码为4.8.13.3上部代码;③ 在URP Asset中启用Depth Texture。
编辑代码:① 在HLSL中引用DeclareDepthTexture.hlsl文件;② 在片段着色器中,通过将像素位置除以渲染目标分辨率_ScaledScreenParams来计算出采样深度缓存的UV坐标(_ScaledScreenParams的属性xy会考虑渲染目标的放缩,例如动态分辨率);③ 在片段着色器中,使用SampleSceneDepth函数对深度缓存取样,该函数返回范围为[0,1]的Z值,来自DeclareDepthTexture.hlsl文件。为了使重建函数ComputeWorldSpacePosition生效,深度值必须在归一化设备坐标NDC空间中,在D3D中Z范围为[0,1],在OpenGL中Z范围为[-1,1](使用常数UNITY_REVERSED_Z来确定平台并调整Z值范围)。该例中,使用常数UNITY_REVERSED_Z来决定平台并调整Z的范围,变量UNITY_NEAR_CLIP_VALUE是依赖于平台裁剪空间的近裁剪面值。④ 由像素的UV坐标、Z坐标重构世界位置:函数ComputeWorldSpacePosition通过UV和深度Z计算世界空间位置,在SRP核心库的Common.hlsl中定义。UNITY_MATRIX_I_VP是一个将点从裁剪面变换到世界空间的逆视图投影矩阵。⑤ 创建棋盘特效,可视化像素的世界空间位置。
Shader "Example/URPUnlitShaderXReconstructPosition"
{
Properties{}
SubShader
{
Tags { "RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline" }
Pass
{
HLSLPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
// ①该DeclareDepthTexture.hlsl文件中包含对摄像机深度纹理进行采样的功能
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareDepthTexture.hlsl"
struct Attributes
{ // 顶点着色器的输入,包含对象空间的顶点坐标
float4 positionOS : POSITION;
};
struct Varyings
{ // 片段着色器的输入,包含SV_POSITION语义
float4 positionHCS : SV_POSITION; // 获取像素的位置
};
// 顶点着色器
Varyings vert(Attributes IN)
{
Varyings OUT; // 声明顶点着色器的输出对象
OUT.positionHCS = TransformObjectToHClip(IN.positionOS.xyz); // 将顶点坐标从对象空间OS变换到齐次裁剪空间HCS
return OUT;
}
// 片段着色器
half4 frag(Varyings IN) : SV_Target // Varyings对象IN包含了顶点着色器的插值
{ // ②UV坐标 = 像素位置 / 渲染分辨率,_ScaledScreenParams.xy会考虑对象的放缩
float2 UV = IN.positionHCS.xy / _ScaledScreenParams.xy;
// ③根据UV对像素的Z坐标(深度)进行取样的SampleSceneDepth函数
#if UNITY_REVERSED_Z // D3D平台
real depth = SampleSceneDepth(UV);
#else // OpenGL平台
real depth = lerp(UNITY_NEAR_CLIP_VALUE, 1, SampleSceneDepth(UV));
#endif
// ④重建世界坐标
float3 worldPos = ComputeWorldSpacePosition(UV, depth, UNITY_MATRIX_I_VP);
// ⑤棋盘花样的尺寸
uint scale = 10;
// abs函数将花样镜像反转到负坐标,uint3将worldPos转为无符号整型
uint3 worldIntPos = uint3(abs(worldPos.xyz * scale));
// &操作符判断奇偶(将表面划分为方格),^操作符翻转方格颜色,例如0,0,0为0,0,0,1为1,1,0,1为0
bool white = ((worldIntPos.x) & 1) ^ (worldIntPos.y & 1) ^ (worldIntPos.z & 1);
half4 color = white ? half4(1,1,1,1) : half4(0,0,0,1); // 根据0或1区分黑白
// 对于未渲染几何体的没有有效深度缓存的区域,涂成黑色
#if UNITY_REVERSED_Z // 当0==far时,深度小于0的区域涂成黑色
if(depth < 0.0001)
return half4(0,0,0,1);
#else // 当1==far时,深度大于1的区域涂成黑色
if(depth > 0.9999)
return half4(0,0,0,1);
#endif
return color;
}
ENDHLSL
}
}
}
4.8.14、ShaderLab的Pass标签(URP)
URP专用的ShaderLab Pass标签。URP不支持下列光照模式标签:Always、ForwardAdd、PrepassBase、PrepassFinal、Vertex、VertexLMRGBM和VertexLM。
光照模式LightMode标签:在执行渲染管线的不同部分时,决定所使用的Pass。若未设置,则默认为SRPDefaultUnlit标签值。
UniversalForward | 该Pass渲染对象几何体,并评估所有光源的贡献。URP在前向渲染中使用该标签。 |
UniversalGBuffer | 该Pass渲染对象几何体,但不评估光源的贡献。URP在延迟渲染中使用该标签。 |
UniversalForwardOnly | 功能与UniversalForward类似,不同点在于,该Pass可用于前向渲染、延迟渲染。在使用延迟渲染,但必须用前向渲染对象时使用。例如,使用延迟渲染某Scene,但该Scene中某个对象的着色器数据不支持GBuffer,如Clear Coat法线。 (若着色器同时使用前向、延迟渲染,则需要分别用UniversalForward和UniversalGBuffer标签声明两个Pass;若着色器只用前向渲染,则使用该标签;若使用了SSAO渲染特性,则需要额外声明一个带DepthNormalsOnly的Pass。) |
DepthNormalsOnly | 该标签在延迟渲染路径中与UniversalForwardOnly结合使用,使着色器在Depth和Normal的Prepass中渲染。若在延迟渲染中没有该标签,则不会在Mesh周围生成环境闭塞。 |
Universal2D | 该Pass渲染对象,并评估2D光源的贡献。URP在2D渲染器中使用。 |
ShaderCaster | 该Pass将对象深度从光源角度渲染到阴影贴图或深度纹理中。 |
DepthOnly | 该Pass只将对象的深度信息从摄像机角度渲染到深度纹理中。 |
Meta | 该Pass只在烘焙光源贴图在Editor中时执行,构建Player时剔除。 |
SRPDerfaultUnlit | 用于在渲染时绘制一个额外的Pass,例如绘制对象轮廓。在前向、延迟渲染中都有效。同时也是LightMode的默认值。 |
UniversalMaterialType标签:在延迟渲染中使用,默认值为Lit。
Lit | 指定着色器类型为Lit。在GBuffer通道期间,Unity使用模板标记使用Lit着色器的像素(镜面反射模型为PBR)。同时也是UniversalMaterialType的默认值。 |
SimpleLit | 指定着色器类型为SimpleLit。在GBuffer通道期间,Unity使用模板标记使用SimpleLit着色器的像素(镜面反射模型为Blinn-Phong)。 |
4.9、渲染Debugger
RenderingDebugger窗口可以可视化不同的光照、渲染和材质性质,有助于识别渲染物体、优化Scene和渲染配置。
4.9.1、打开RenderingDebugger窗口
RenderingDebugger窗口可以在Editor、Play模式和独立的Player下打开。(当在开发build中打开时,要在Project Settings-> Graphics-> URP Global Settings中取消勾选Strip Debug Variants。)在Editor中,通过Window-> Analysis -> Rendering Debugger或按Ctrl+退格键打开。在Player模式或开发build中时,若在台式机上,按左Ctrl+退格键;若在手柄上,按L3和R3;若在手机上,用三根手指双击,来打开。
4.9.2、RenderingDebugger窗口功能
Frequently Used:在Material、Lighting和Rendering模块中经常使用的功能。
4.9.2.1、Material模块
Material:可视化不同的材质性质。
Material Filters:过滤不同的材质。
Material Override | 选择一个材质形状,并在屏幕中的每一个游戏对象上可视化。可选Albedo、Specular、Alpha、Smoothness、AmbientOcclusion、Emission、LightingComplexity和Metallic等。 (选择LightingComplexity时,显示影响该屏幕区域的光源数量。) |
Vertex Attribute | 选择一个游戏对象的顶点特性,并在屏幕上可视化。可选Texcoord0、Texcoord1、Texcoord2、Texcoord3、Color、Tangent和Normal。 |
Material Validation:Material Validation Mode用于选择可视化的材质性质(Albedo或Metallic),选择不同的属性出现不同的项。
Albedo模式 | Validation Preset:选择一个预设材质或默认亮度,来可视化亮度范围。 Min Luminance:亮度低于该值的像素绘制为红色。 Max Luminance:亮度高于该值的像素绘制为蓝色。 Hue Tolerance:色相容差,选择预设材质时可用。将色相容差加到最小、最大亮度上。 Saturation Tolerance:饱和容差,选择预设材质时可用。将饱和容差加到最小、最大亮度上。 |
Metallic模式 | Min Value:metallic值低于该值的像素绘制为红色。 Max Value:metallic值高于该值的像素绘制为蓝色。 |
4.9.2.2、Lighting模块
Lighting:可视化不同的光照系统的设置和元素,例如阴影级联、反射和主要光源、额外光源的贡献等。
Lighting Debug Mode | 指定覆盖在屏幕上调试的光照阴影信息。 None:正常渲染,不做调试覆盖。 Shadow Cascades:覆盖阴影级联信息,可以看到每个像素都需要的阴影级联。 Lighting Without Normal Maps:可视化光照,使用中性材质并禁用法线贴图。可用于调试法线贴图引起的光照问题。 Lighting With Normal Maps:可视化光照,使用中性材质并启用法线贴图。 Reflections:可视化反射,使用可反射的绝对光滑材质。 Reflections Without Smoothness:可视化反射,使用可反射材质,以正常的光滑度。 |
Lighting Features | 指定对最终光照结果有贡献的光照特性的标记,用于查看和调试特定的光照特性。 Nothing:禁用所有的标记。 Everything:启用所有的标记。 Global Illumination:是否渲染全局照明。 Main Light:主平行光是否有贡献。 Additional Light:主平行光以外的额外光源是否有贡献。 Vertex Lighting:额外光源中使用逐像素光照per-vertex lighting的光源是否有贡献。 Emission:发光材质是否有贡献。 Ambient Occlusion:环境光闭塞是否有贡献。 |
4.9.2.3、Rendering模块
Map Overlays | 指定覆盖在屏幕上的渲染管线纹理。 None:正常渲染,不覆盖纹理。 Depth:覆盖摄像机的深度纹理。 Additional Lights Shadow Map:覆盖包含除主平行光外其他光源投射的阴影的阴影贴图。 Main Light Shadow Map:覆盖包含主平行光投射的阴影的阴影贴图。 |
Map Size | 覆盖纹理的宽度、高度,以View窗口的百分比。例如,50代表填满屏幕的四分之一。 |
HDR | 是否使用HDR渲染。仅在启用HDR时有效。 |
MSAA | 是否使用MSAA。仅在Game视图中切启用Anti Alising时有效。 |
Post-processing | 使用post-processing的方式。 Disabled:禁用post-processing。 Auto:基于当前活动的调试模式启用/禁用post-processing。若后期处理的颜色变化会改变像素的调试模式,将禁用;若颜色变化不改变调试模式或没有活动的调试模式,将启用。 Enabled:将后期处理应用到摄像机捕获的图像上。 |
Additional Wireframe Modes | 指定是否/如何在Scene中为Mesh渲染线框图wireframe。 None:不渲染线框图。 Wireframe:以独有方式渲染Scene中Mesh的边,可以通过较近的Mesh的线框图来看Mesh。 Solid Wireframe:以独有方式渲染Scene中Mesh的边和面,每个线框图Mesh的面将其边隐藏。 Shaded Wireframe:将Mesh的边渲染为覆盖层,以彩色渲染Scene,并将线框图覆盖在上面。 |
Overdraw | 是否渲染过度绘制,可以看出哪些像素绘制在其他像素上面。 |
Pixel Validation Mode | 验证像素颜色值的模式。 None:正常渲染,不验证任何像素。 Highlight NaN, Inf and Negative Values:将颜色值为NaN、Inf和负值的像素标高亮。 Highlight Values Outside Range:将颜色值超出特定范围的像素标高亮,使用Channels、Value Range Min和Value Range Max来确定范围。 |
Channels | 用于像素范围验证的RGBA值。可选:RGB、R、G、B、A。 |
Value Range Min | 验证颜色值的下界,低于该值的颜色值被标高亮。 |
Value Range Max | 验证颜色值的上界,高于该值的颜色值被标高亮。 |
5、高清渲染管线 HDRP
官方文档:HDRP 12.1.7
(未完待续)
11111111