查看: 64|回复: 1

Unity 手把手教你从Built-in升级URP

[复制链接]

1

主题

5

帖子

9

积分

新手上路

Rank: 1

积分
9
发表于 2023-7-25 15:49:13 | 显示全部楼层 |阅读模式
一、前言

URP正式发布已经很久了,现在是2023年,但是发现现在网上的一些Shader教程还是大多都是基于Built-in的,感觉对于新手同学们不是很友好,关于URP的教程又少之又少。
这里结合个人经验以及网络上的一些资料,介绍一下如何从Built-in升级到URP。


<hr/>二、项目设置升级URP

1、从Package Manager下载Universal RP

在导航栏中Window->Package Manager,搜索Universal RP


2、将项目设置中的管线配置为URP

首先需要生成URP相关Asset资产
在导航栏中Assets ->Create -> Rendering - >Universal Render Pipeline -> Pipeline Asset创建





创建完后默认名称

然后在导航栏的Edit中打开Project Setting面板


选择Graphics,然后再其中的Scriptable Render Pipeline settings中选择UniversalRenderPipelineAsset


注意如果项目做不同的品质设置,到Quality里每一栏都指定对应的UniversalRenderPipelineAsset



最好做项目的时候都设置一下,有时候这里没设置可能有坑

3.将系统默认的材质升级到URP

操作完第二步后,发现场景里的颜色变成了粉色,此时不要慌

  • 如果是Built-In的默认标准材质,那么可以通过URP提供的工具改回来
  • 如果是自己编写的Shader需要重新编写一下代码(后面会从Shader代码的角度讲解怎么升级)


在导航栏中Edit -> Render Pipeline -> Universal Render Pipeline -> Upgrade Project Material to UniversalRP Materials




主要的操作就是将原来旧材质球里用到了的默认shader替换为urp里对应的shader



如果用的不是系统自带的Shader那么将不能转换



转换失败的例子

至此Unity设置方面已经完成
<hr/>三、Shader代码升级

强烈建议用Jetbrains Rider做开发工具,Shader代码高亮和补全用得很舒服
参靠来源:
URP管线比较大的变化就是,不再支持多个渲染Pass
在Built-in里面,前向渲染的方式为

  • ForwardBase Pass计算主光
  • ForwardAdd Pass计算其他光照
光源越多调用的Pass数量就越多
在URP里面,采用的是在一个Pass中遍历所有光源进行计算
1.Unlit Shader举例

我们这里先拿一个最简单的Unlit Shader进行举例说明
Built-in
Shader "Unlit/test_CG"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
        _Color("Base Color",Color)=(1,1,1,1)
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100

        Pass
        {
            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;
            float4 _Color;

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                UNITY_TRANSFER_FOG(o,o.vertex);
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                // sample the texture
                fixed4 col = tex2D(_MainTex, i.uv);

                return col * _Color;
            }
            ENDCG
        }
    }
}
URP(HLSL)
Shader "Unlit/test_URP"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
        _Color("Base Color",Color)=(1,1,1,1)
    }
    SubShader
    {
        Tags {  
            "RenderPipeline"="UniversalPipeline"//声明这是一个URP Shader!
            "Queue"="Geometry"
            "RenderType"="Opaque" }
        LOD 100

        
        HLSLINCLUDE //在Pass外部,引入文件或者定义,均在HLSLINCLUDE 完成
        //用于替换 CG中核心代码库 #include "UnityCG.cginc"
        #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"//函数库:主要用于各种的空间变换
        TEXTURE2D(_MainTex); SAMPLER(sampler_MainTex); //采样贴图,采样前面汇入的maintex贴图,贴图采样器,以及贴图st

         //除了贴图外,在片元Shader中使用到的暴露在Inspector面板上的变量,都需要缓存到CBUFFER中,用于 SRP Batcher
        CBUFFER_START(UnityPerMaterial)
        float4 _MainTex_ST;
        float4 _Color;
        CBUFFER_END
        
        ENDHLSL

        Pass
        {
            // CGPROGRAM
            HLSLPROGRAM //替换掉 CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            // #include "UnityCG.cginc"
            // Pass 外已经引入了 Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl
            
            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                float4 vertex : SV_POSITION;
            };

            
            v2f vert (appdata v)
            {
                v2f o;
                // o.vertex = UnityObjectToClipPos(v.vertex);
                o.vertex = TransformObjectToHClip(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                return o;
            }

            //fixed4 不再URP中支持,需要用half4 或者 float4
            float4 frag (v2f i) : SV_Target
            {
                // sample the texture
                // fixed4 col = tex2D(_MainTex, i.uv);
                //HLSL 里贴图采样函数需要替换
                float4 col = SAMPLE_TEXTURE2D(_MainTex,sampler_MainTex, i.uv);

                return col * _Color;
            }
//            ENDCG
            ENDHLSL  
        }
    }
}
我在代码里做了一些注释,可以看到转换时都有哪些修改项,基本对照着类似的进行改动即可完成Shader的升级
这只是个简单的例子,后面我们详细的来对照讲解。
2.Built-in到URP函数对照整理

整体结构

  • 需要在Tag里添加"RenderPipeline" = "UniversalPipeline"
  • 所有的URP Shader代码均包含在HLSLPROGRAM/ENDHLSL 内
Built-inURP
CGPROGRAM
HLSLPROGRAM
HLSLPROGRAM
ENDCG
ENDHLSL
ENDHLSL
CGINCLUDE
HLSLINCLUDE
HLSLINCLUDE
Include文件:
ContentBuilt-inURP
CoreUnity.cgincPackages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl
LightAutoLight.cgincPackages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl
ShadowsAutoLight.cgincPackages/com.unity.render-pipelines.universal/ShaderLibrary/Shadows.hlsl
Surface shadersLighting.cgincURP内不支持
所有的HLSL代码均在Packages/Universal RP内,可以翻看详细源码


Light Modes(照明模式)
Built-inURP
ForwardBaseUniversalForward
ForwardAdd移除
Deferred and related尚未支持
Vertex and related移除
ShadowCasterShadowCaster
MotionVectors尚未支持
还有一些其他的Light Modes:

  • DepthOnly
  • Meta (for lightmap baking)
  • Universal2D

Variants(变体)
URP支持某些变体,需要根据你使用的功能#pragma multi_compile添加一些关键字:

  • _MAIN_LIGHT_SHADOWS
  • _MAIN_LIGHT_SHADOWS_CASCADE
  • _ADDITIONAL_LIGHTS_VERTEX
  • _ADDITIONAL_LIGHTS
  • _ADDITIONAL_LIGHT_SHADOWS
  • _SHADOWS_SOFT
  • _MIXED_LIGHTING_SUBTRACTIVE
预定义的着色器宏
Built-inURP
UNITY_PROJ_COORD(a)使用a.xy / a.w代替
UNITY_INITIALIZE_OUTPUT(type, name)ZERO_INITIALIZE(type,name)

Shadow Mapping(阴影贴图)
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Shadows.hlsl"
Built-inURP
UNITY_DECLARE_SHADOWMAP(tex)TEXTURE2D_SHADOW_PARAM(textureName, samplerName)
UNITY_SAMPLE_SHADOW(tex, uv)SAMPLE_TEXTURE2D_SHADOW(textureName, samplerName, coord3)
UNITY_SAMPLE_SHADOW_PROJ(tex, uv)SAMPLE_TEXTURE2D_SHADOW(textureName, samplerName, coord4.xyz/coord4.w)

Texture/Sampler Declaration Macros(纹理贴图采样)
这里仅列举一些常用的,更多的可以查看API includes
Built-inURP
UNITY_DECLARE_TEX2D(name)TEXTURE2D(textureName); SAMPLER(samplerName);
UNITY_DECLARE_TEX2D_NOSAMPLER(name)TEXTURE2D(textureName);
UNITY_DECLARE_TEX2DARRAY(name)TEXTURE2D_ARRAY(textureName); SAMPLER(samplerName);
UNITY_SAMPLE_TEX2D(name, uv)SAMPLE_TEXTURE2D(textureName, samplerName, coord2)
UNITY_SAMPLE_TEX2D_SAMPLER(name, samplername, uv)SAMPLE_TEXTURE2D(textureName, samplerName, coord2)
UNITY_SAMPLE_TEX2DARRAY(name, uv)SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index)
UNITY_SAMPLE_TEX2DARRAY_LOD(name, uv, lod)SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod)

Shader辅助函数
代码文件可以查看:
顶点转换函数
Built-inURP
float4 UnityObjectToClipPos(float3 pos)float4 TransformObjectToHClip(float3 positionOS)
float3 UnityObjectToViewPos(float3 pos)TransformWorldToView(TransformObjectToWorld(positionOS))
法线转换函数
Built-inURP
float4 UnityObjectToWorldNormal(float3 pos)float4 TransformObjectToWorldNormal(float3 normalOS)
通用辅助函数
Built-inURP
float3 WorldSpaceViewDir (float4 v)float3 GetWorldSpaceViewDir(float3 positionWS)Include “Packages/com.unity.render-pipelines.universal/ShaderLibrary/ShaderVariablesFunctions.hlsl”
float3 UnityObjectToWorldDir(float4 v)TransformObjectToWorldDir(real3 dirOS)
float3 ObjSpaceViewDir(float4 v)移除了,可以使用TransformWorldToObject(GetCameraPositionWS()) - objectSpacePosition ;
float2 ParallaxOffset (half h, half height, half3 viewDir)移除了。可以从UnityCG.cginc复制过来
fixed Luminance (fixed3 c)real Luminance(real3 linearRgb)Include “Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl”
fixed3 DecodeLightmap (fixed4 color)real3 DecodeLightmap(real4 encodedIlluminance, real4 decodeInstructions)Include “Packages/com.unity.render-pipelines.core/ShaderLibrary/EntityLighting.hlsl” URP中的decodeInstructions是half4(LIGHTMAP_HDR_MULTIPLIER, LIGHTMAP_HDR_EXPONENT, 0.0h, 0.0h)
float4 EncodeFloatRGBA(float v)移除了。可以从UnityCG.cginc复制过来
float DecodeFloatRGBA(float4 enc)移除了。可以从UnityCG.cginc复制过来
float2 EncodeFloatRG(float v)移除了。可以从UnityCG.cginc复制过来
float DecodeFloatRG(float2 enc)移除了。可以从UnityCG.cginc复制过来
float2 EncodeViewNormalStereo(float3 n)移除了。可以从UnityCG.cginc复制过来
float3 DecodeViewNormalStereo(float4 enc4)移除了。可以从UnityCG.cginc复制过来
前向渲染辅助函数
Built-inURP
float3 WorldSpaceLightDir (float4 v)_MainLightPosition.xyz - TransformObjectToWorld(objectSpacePosition)Include “Packages/com.unity.render-pipelines.universal/ShaderLibrary/Input.hlsl”
float3 ObjSpaceLightDir (float4 v)TransformWorldToObject(_MainLightPosition.xyz) - objectSpacePositionInclude “Packages/com.unity.render-pipelines.universal/ShaderLibrary/Input.hlsl”
float3 Shade4PointLights (…)可以使用half3 VertexLighting(float3 positionWS, half3 normalWS)对于VertexLighting(...) include “Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl”
屏幕空间辅助函数
Built-inURP
float4 ComputeScreenPos (float4 clipPos)float4 ComputeScreenPos(float4 positionCS)Include “Packages/com.unity.render-pipelines.universal/ShaderLibrary/ShaderVariablesFunctions.hlsl”
float4 ComputeGrabScreenPos (float4 clipPos)移除了
顶点照明辅助函数
Built-inURP
loat3 ShadeVertexLights (float4 vertex, float3 normal)移除了,可以尝试使用UNITY_LIGHTMODEL_AMBIENT.xyz + VertexLighting(...)对于VertexLighting(...) include “Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl”
内置着色器变量
除了光照相关的变量外,其他的变量名都基本没变
Lighting(照明)
Built-inURP
_LightColor0_MainLightColorInclude “Packages/com.unity.render-pipelines.universal/ShaderLibrary/Input.hlsl”
_WorldSpaceLightPos0_MainLightPositionInclude “Packages/com.unity.render-pipelines.universal/ShaderLibrary/Input.hlsl”
_LightMatrix0移除了。目前尚不支持Cookie
unity_4LightPosX0, unity_4LightPosY0, unity_4LightPosZ0在URP中,其他光源存储在数组/缓冲区中(取决于平台)。使用Light GetAdditionalLight(uint i, float3 positionWS)获取额外光源信息Include “Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl”
unity_4LightAtten0在URP中,其他光源存储在数组/缓冲区中(取决于平台)。使用Light GetAdditionalLight(uint i, float3 positionWS)获取额外光源信息Include “Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl”
unity_LightColor在URP中,其他光源存储在数组/缓冲区中(取决于平台)。使用Light GetAdditionalLight(uint i, float3 positionWS)获取额外光源信息Include “Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl”
unity_WorldToShadowfloat4x4 _MainLightWorldToShadow[MAX_SHADOW_CASCADES + 1] 或者_AdditionalLightsWorldToShadow[MAX_VISIBLE_LIGHTS]Include “Packages/com.unity.render-pipelines.universal/ShaderLibrary/Shadows.hlsl”
如果要使用循环所有其他灯光GetAdditionalLight(...),GetAdditionalLightsCount()可以使用来查询其他灯光计数。

其他
Shadows(阴影)
Built-inURP
UNITY_SHADOW_COORDS(x)移除了。DIY,例如float4 shadowCoord : TEXCOORD0;
TRANSFER_SHADOW(a)a.shadowCoord = TransformWorldToShadowCoord(worldSpacePosition)
SHADOWS_SCREEN移除了
Fog(雾)
Built-inURP
UNITY_FOG_COORDS(x)移除了。DIY,例如float fogCoord : TEXCOORD0;
UNITY_TRANSFER_FOG(o*,outpos)o.fogCoord = ComputeFogFactor(clipSpacePosition.z);
UNITY_APPLY_FOG(coord,col)color = MixFog(color,i.fogCoord);
Depth(深度)
要使用相机深度纹理,需要include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareDepthTexture.hlsl" ,然后会自动声明_CameraDepthTexture,也会包含辅助函数SampleSceneDepth(...)和LoadSceneDepth(...)
Built-inURP
LinearEyeDepth(sceneZ)LinearEyeDepth(sceneZ, _ZBufferParams)Include “Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl”
Linear01Depth(sceneZ)Linear01Depth(sceneZ, _ZBufferParams)Include “Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl”
其他
Built-inURP
ShadeSH9(normal)SampleSH(normal)Include “Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl”
unity_ColorSpaceLuminance移除了。使用Luminance()Include “Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl”
基本上Shader代码对照上述整理的内容,做完更替后即可完成升级。

四、尾语

另外关于SRP Batcher-URP的优化实践,可以参考我之前写的文章
关于Unity不同的渲染管线的区别,可以参考这个回答:
以上内容部分部分来自自我实践,部分来自网络整理。
如果看完对你有帮助的话,麻烦点个赞或者点个关注嘞!
回复

使用道具 举报

2

主题

4

帖子

9

积分

新手上路

Rank: 1

积分
9
发表于 2023-7-25 15:49:20 | 显示全部楼层
根本就搜不到Universal RP
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|小棋牌

GMT+8, 2025-3-15 19:45 , Processed in 0.107762 second(s), 22 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表