Unity内置渲染管线升级URP教程

简介

URP全称为Universal Render Pipeline(通用渲染管线),可以提供更加灵活的渲染方案,通过添加Render Feature实现各种渲染效果。并且可以针对移动平台进行专门的优化,同时还提供了SRPBatcher提高渲染效率。Unity的一些工具,比如ShaderGraph,也是必须在URP管线下才可以使用,可以说许多方面均优于内置渲染管线。

所以如果还在使用内置渲染管线的,建议尽早升级到URP。通过本文,可以了解到如何从内置管线升级到URP。并且记录了一些升级时可能遇到的问题和解决方法。

一、安装并配置URP

1.安装对应package

Unity内置渲染管线升级URP教程_第1张图片

2.创建配置

Create->rendering->Universal pipeline->Pipeline Asset(Forward Renderer)生成两个配置文件(目前放在Pipeline文件夹下)

Unity内置渲染管线升级URP教程_第2张图片

Edit->Project Settings->Graphics 界面,将UniversalRenderPipelineAsset拖入

Unity内置渲染管线升级URP教程_第3张图片

3.统一升级自带的shader

Edit->Render Pipeline->Universal Render Pipeline-> Upgrade Project Materials to Universal PR Materials

可以将使用默认built-inShader升级到URP的Shader

二、关于内置管线升级至URP管线的问题处理

在未使用URP管线的时候,由于一些shader是使用CG语言写的,而URP并不支持该语言。所以需要将其改为HLSL(High level shader language)编写。

查看对应源文件

1、cginc文件的内置函数可以在Editor引擎安装目录下查看  xxx\Editor\2020.1.0f1c1\Editor\Data\CGIncludes

2、hlsl文件则是在工程对应的Library文件下可以找到:

以Core.hlsl为例子,头文件路径为

Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl

实际在工程中的位置是

xxx\ProjectName\Library\PackageCache\[email protected]\ShaderLibrary\Core.hlsl

宏替换

C#
CGPROGRAM    ENDCG    //替换前是CG语言的宏 

HLSLPROGRAM    ENDHLSL    //替换后使用HLSL语言的宏

包含的头文件替换

C#
#include "UnityCG.cginc"//替换前
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"//替换后

//----------------------------分割线---------------------------------------

#include "Lighting.cginc"//替换前
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"//替换后
  

Tag替换

C#
Tags { "LightMode" = "ForwardBase" } //替换前
Tags { "RenderPipeline" = "UniversalPipeline" }//替换后

Texutre2D的处理

C#
uniform sampler2D _BumpMap; //替换前是一个sampler2D变量
TEXTURE2D(_MainTex);//替换后需要使用两个变量 TEXTURE2D和sampler
SAMPLER(sampler_MainTex);

//----------------------------分割线---------------------------------------

float4 mainColor = tex2D(_MainTex, i.tex);//替换前对texture2d的采样是两个参数
float4 mainColor = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.tex);//替换后是
//三个参数的函数,前两个参数,就是一开始对声明替换时的两个参数.
 

参考文档

升级Urp

https://www.jianshu.com/p/3fef69e2efb6

https://zhuanlan.zhihu.com/p/147228689

三、场景内组件修改

1.多相机修改

URP管线相机不再支持相机的depth属性。主摄像机RenderType设置为base。其他的摄像机的RenderType 都是Overlay类型。

Unity内置渲染管线升级URP教程_第4张图片

并且需要将其他相机加入到主相机的Stack中

Unity内置渲染管线升级URP教程_第5张图片

四、如何启用SRPBatcher

SRP Batcher 是一个渲染循环,可通过许多使用同一着色器变体的材质来加快场景中的 CPU 渲染速度。虽然不会减少DC的次数,但是SRPBatcher可以降低准备DC数据的耗时。相关的官方文档https://docs.unity3d.com/cn/2020.2/Manual/SRPBatcher.html

注意事项

同一个Shader不能同时启用SRP Batcher或者Gpu Instance。并且SRP Batcher的优先级是最高的。会导致原先可以合批的DC被打断。

1.设置

需要在URP设置中的Advaneced->SRP Batcher打开

Unity内置渲染管线升级URP教程_第6张图片

2.修改Shader以支持SRPBatcher

需要用CBUFFER_START(UnityPerMaterial)CBUFFER_END,将所有Properties内声明的变量包住。例子如下:

C#
Properties
{
    _Tint("_Tint", Color) = (1,1,1,1)
    _MainTex("_MainTex (albedo)", 2D) = "white" {}
    _Specular ("Specular", Color) = (1, 1, 1, 1)
    _Gloss ("Gloss", Range(8.0, 256)) = 80
 }
SubShader
{
     Pass
     {
         CBUFFER_START(UnityPerMaterial)//这里是添加的代码
         TEXTURE2D(_MainTex);
         SAMPLER(sampler_MainTex);
         float4 _MainTex_ST;
         float4 _Specular;
         float _Gloss;
         half4 _Tint;
         CBUFFER_END//这里是添加的代码
      }
}

需要注意的是,像Properties内的纹理变量,虽然声明的时候只有一个变量,但是相关的SAMPLER变量也要包在CBUFFER内。

Unity内置渲染管线升级URP教程_第7张图片

修改后如果支持SRPBatcher,在对应shader的Inspector界面的SRPBatcher属性会显示为compatible

如果是不支持SRPBatcher的Shader对应Shader的SRPBatcher属性会显示为not compatible,并且会显示不支持的原因

3.SRPBatcher性能优化的检测工具

1.添加SRPBatcherProfiler.cs文件添加到工程中,代码库地址是https://github.com/Unity-Technologies/SRPBatcherBenchmark

2.将SRPBatcherProfiler脚本拖到需要进行检测的场景中,点击F8显示/隐藏SRPBatcherProfiler界面,点击F9打开/关闭(实际发现F9功能不好使,无法中途打开关闭)SRPBatcher功能。可以对比打开该功能前后的CPU消耗情况。

.升级URP之后的一些异常现象

1.Culling mask导致光照的表现不同

升级URP后发现物体的光照表现不太一样。经过测试发现,在内置管线时,light的Culling mask是有效的,而在URP下,Culling mask失效了。多光源的情况下,HLSL和GC两个Shader通过GetMainLight获取的光线都是不同的。

处理方式是获取所有的AddtionalLight,然后根据light的distanceAttenuation值去判断,哪个光源是真正作用在目标物体上的。(Culling mask校验通过的光源light.distanceAttenuation不为0)

C#
                Light light = GetMainLight();
                if( light.distanceAttenuation == 0)
                {
                     int addLightsCount = GetAdditionalLightsCount();//定义在lighting库函数的方法 返回一个额外灯光的数量
                     for (int idx = 0; idx < addLightsCount; idx++)
                     {
                        Light addlight = GetAdditionalLight(idx, i.worldPos);//定义在lightling库里的方法 返回一个灯光类型的数据
                        if(addlight.distanceAttenuation>0)
                        {
                            light = addlight;
                            break;
                        }
                     }
                }

2.Frame Debugger显示异常

2020.3.36f1c1版本中,打开FrameDebugger。场景并不会随着渲染阶段而变化

Unity内置渲染管线升级URP教程_第8张图片

Unity内置渲染管线升级URP教程_第9张图片

找到相关文章,该问题是Unity的Bug,在关闭urp的msaa选项之后,FrameDebugger就可以正常显示

Unity内置渲染管线升级URP教程_第10张图片

3.报错 Shader properties can't be added to this global property sheet. Trying to add _GrabTexture_TexelSize (type 1 count 1)

UnityEngine.GUIUtility:ProcessEvent (int,intptr,bool&)

Shader properties can't be added to this global property sheet. Trying to add _GrabTexture_HDR (type 1 count 1)

UnityEngine.GUIUtility:ProcessEvent (int,intptr,bool&)

这个是因为URP不支持GrabPass导致,处理方法是将Shader中无用的GrabPass删除,如果需要用到屏幕截图,修改成HLSL语言,然后利用SAMPLER(_CameraOpaqueTexture);来代替grabTexture

你可能感兴趣的:(Unity开发方案和知识,unity,前端,游戏引擎,图形渲染)