添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

内置管线 Shader 升级到 URP 详细手册

1、在 SubShader 的 Tags 中添加 "RenderPipeline" = "UniversalPipeline"
2、所有 URP 着色器都是 HLSL 编写的,使用宏 HLSL 包含的 shader 代码
3、使用 HLSLINCLUDE 替代 CGINCLUDE

内置管线 URP
CGPROGRAM HLSLPROGRAM HLSL程序
ENDCG ENDHLSL ENDHLSL
CGINCLUDE HLSLINCLUDE HLSLINCLUDE

Include文件

内容 内置管线 URP
Core UnityCG.cginc Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl
Light AutoLight.cginc Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl
Shadow AutoLight.cginc Packages/com.unity.render-pipelines.universal/ShaderLibrary/Shadows.hlsl
表面着色器 Lighting.cginc URP 内没有,可以参考项目: 在此处
其他有用的包括:
  • Packages/com.unity.render-pipelines.core/ShaderLibrary/SpaceTransforms.hlsl
  • Packages/com.unity.render-pipelines.universal/ShaderLibrary/ShaderVariablesFunctions.hlsl
  • Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl
  • Packages/com.unity.render-pipelines.universal/ShaderLibrary/Input.hlsl
  • Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl
  • Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareDepthTexture.hlsl
  • Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareOpaqueTextue.hlsl
  • 灯光模式 LightMode

    内置管线 URP
    ForwardBase UniversalForward
    ForwardAdd 移除
    Deferred 以及相关 尚未支持
    Vertex 及相关 移除
    ShadowCaster ShadowCaster
    MotionVectors 尚未支持

    支持的其他照明模式包括:

  • 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
  • 预定义的着色器宏

    内置管线 URP
    UNITY_PROJ_COORD ( a ) 移除了,使用 a.xy / a.w 代替
    UNITY_INITIALIZE_OUTPUT ( type name ) ZERO_INITIALIZE ( type name )

    必须 include “Packages/com.unity.render-pipelines.universal/ShaderLibrary/Shadows.hlsl”

    内置管线 URP
    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

    纹理/采样器声明宏

    Unity 有很多纹理/采样器宏来改善 API 之间的交叉兼容性,但是人们并不习惯使用它们。URP 中这些宏的名称有所变化。由于数量很多,全部的宏可以在 API includes中 查看,下面主要列举一些常用的:

    内置管线 URP
    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

    需要注意 SCREENSPACE_TEXTURE 变成了 TEXTURE2D_X 。如果你想要在 VR 中( Single Pass Instanced Multi-view 模式)制作屏幕效果,你必须使用 TEXTURE2D_X 定义纹理。这个宏会为你处理正确的纹理声明(是否为数组)。对这个纹理采样的时候必须使用 SAMPLE_TEXTURE2D_X ,并且对 uv 使用 UnityStereoTransformScreenSpaceTex

    Shader 辅助函数

    下列函数可以在此文件中找到: “Packages/com.unity.render-pipelines.core/ShaderLibrary/SpaceTransforms.hlsl” .

    顶点转换函数

    内置管线 URP
    float4 UnityObjectToClipPos float3 pos float4 TransformObjectToHClip float3 positionOS
    float3 UnityObjectToViewPos float3 pos TransformWorldToView TransformObjectToWorld positionOS ))

    法线转换函数

    内置管线 URP
    float4 UnityObjectToWorldNormal float3 pos float4 TransformObjectToWorldNormal float3 normalOS

    通用辅助函数

    内置管线 URP
    float3 UnityWorldSpaceViewDir float4 v GetCameraPositionWS() - i.worldPos
    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 复制过来
    TANGENT_SPACE_ROTATION

    前向渲染辅助函数

    内置管线 URP
    float3 UnityWorldSpaceLightDir ( float4 v ) _MainLightPosition.xyz - TransformObjectToWorld ( objectSpacePosition ) Include “Packages/com.unity.render-pipelines.universal/ShaderLibrary/Input.hlsl”
    float3 ObjSpaceLightDir ( float4 v ) TransformWorldToObject ( _MainLightPosition.xyz ) -objectSpacePosition Include “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”

    屏幕空间辅助函数

    内置管线 URP
    float4 ComputeScreenPos ( float4 clipPos ) float4 ComputeScreenPos float4 positionCS Include “Packages/com.unity.render-pipelines.universal/ShaderLibrary/ShaderVariablesFunctions.hlsl”
    float4 ComputeGrabScreenPos ( float4 clipPos ) 移除了

    顶点照明辅助函数

    内置管线 URP
    float3 ShadeVertexLights ( float4 vertex , float3 normal ) 移除了,可以尝试使用 UNITY_LIGHTMODEL_AMBIENT.xyz + VertexLighting(...) 对于 VertexLighting(...) include “Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl”

    可以在 “Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl” 中找到很多工具函数。

    内置着色器变量

    除了光照相关的变量外,其他的变量名都基本没变

    内置管线 URP
    _LightColor0 _MainLightColor Include “Packages/com.unity.render-pipelines.universal/ShaderLibrary/Input.hlsl”
    _WorldSpaceLightPos0 _MainLightPosition Include “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_WorldToShadow float4x4 _MainLightWorldToShadow[MAX_SHADOW_CASCADES + 1] 或者 _AdditionalLightsWorldToShadow[MAX_VISIBLE_LIGHTS] Include “Packages/com.unity.render-pipelines.universal/ShaderLibrary/Shadows.hlsl”

    如果要使用循环所有其他灯光 GetAdditionalLight(...) GetAdditionalLightsCount() 可以使用来查询其他灯光计数。

    有关阴影的更多信息, “Packages/com.unity.render-pipelines.universal/ShaderLibrary/Shadows.hlsl”

    内置管线 URP
    UNITY_SHADOW_COORDS x 移除了。DIY,例如 float4 shadowCoord : TEXCOORD0;
    TRANSFER_SHADOW a a.shadowCoord = TransformWorldToShadowCoord worldSpacePosition 启用 cascades 时,对片段执行此操作以避免视觉鬼影
    SHADOWS_SCREEN 移除了。不支持。

    有关雾的更多信息, “Packages/com.unity.render-pipelines.universal/ShaderLibrary/ShaderVariablesFunctions.hlsl” .

    内置管线 URP
    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 );

    要使用相机深度纹理,需要 include “Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareDepthTexture.hlsl” ,然后会自动声明 _CameraDepthTexture ,也会包含辅助函数 SampleSceneDepth(...) LoadSceneDepth(...)

    内置管线 URP
    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”

    其他中的其他

    内置管线 URP
    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”

    后处理/视觉特效

    URP 不支持 OnPreCull OnPreRender OnPostRender OnRenderImage 这些方法。URP 支持 OnRenderObject OnWillRenderObject ,但是如果在 URP 中使用你可能会发现问题。因此,如果你曾经在旧管线创建视觉效果时使用它们,那么现在你需要学习新方法了。URP包含以下注入点:

  • beginCameraRendering(ScriptableRenderContext context, Camera camera)
  • endCameraRendering(ScriptableRenderContext context, Camera camera)
  • beginFrameRendering(ScriptableRenderContext context,Camera[] cameras)
  • endFrameRendering(ScriptableRenderContext context,Camera[] cameras)
  • 用法示例:

    void OnEnable()
        RenderPipelineManager.beginCameraRendering += MyCameraRendering;
    void OnDisable()
        RenderPipelineManager.beginCameraRendering -= MyCameraRendering;
    void MyCameraRendering(ScriptableRenderContext context, Camera camera)
        if(camera == myEffectCamera)
    

    就像我说的那样,OnWillRenderObject 是受支持的,但是,如果你需要在其中执行渲染调用(例如,水反射/折射),它将无法正常工作。调用 Camera.Render(),你将看到以下消息:

    Recursive rendering is not supported in SRP (are you calling Camera.Render from within a render pipeline?)

    翻译过来就是:

    SRP 不支持递归渲染(你是从渲染管道中调用 Camera.Render 吗?)

    在这种情况下,URP 中应该将 OnWillRenderObject 替换为 begin/endCameraRendering(如上面的例子),并调用 RenderSingleCamera(),而不是 Camera.Render()。更改上面的示例,你将获得以下内容

    void MyCameraRendering(ScriptableRenderContext context, Camera camera)
        if(camera == myEffectCamera)
            UniversalRenderPipeline.RenderSingleCamera(context, camera);
    

    使用后处理的另一种方法是使用 ScriptableRendererFeature这篇文章很好地解释了使用 RenderFeature 的描边效果。ScriptableRendererFeature 可以让你将 ScriptableRenderPass(es) 注入到渲染管线的不同阶段,因此是创建后处理效果的强大工具。注入位置可以包含以下:

  • BeforeRendering
  • BeforeRenderingShadows
  • AfterRenderingShadows
  • BeforeRenderingPrepasses
  • AfterRenderingPrePasses
  • BeforeRenderingOpaques
  • AfterRenderingOpaques
  • BeforeRenderingSkybox
  • AfterRenderingSkybox
  • BeforeRenderingTransparents
  • AfterRenderingTransparents
  • BeforeRenderingPostProcessing
  • AfterRenderingPostProcessing
  • AfterRendering
  • 这是 ScriptableRendererFeature 使用自定义材质执行 Blit 的简单示例:

    public class CustomRenderPassFeature : ScriptableRendererFeature
        class CustomRenderPass : ScriptableRenderPass
            CustomRPSettings _CustomRPSettings;
            RenderTargetHandle _TemporaryColorTexture;
            private RenderTargetIdentifier _Source;
            private RenderTargetHandle _Destination;
            public CustomRenderPass(CustomRPSettings settings)
                _CustomRPSettings = settings;
            public void Setup(RenderTargetIdentifier source, RenderTargetHandle destination)
                _Source = source;
                _Destination = destination;
            public override void Configure(CommandBuffer cmd, RenderTextureDescriptor cameraTextureDescriptor)
                _TemporaryColorTexture.Init("_TemporaryColorTexture");
            public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
                CommandBuffer cmd = CommandBufferPool.Get("My Pass");
                if (_Destination == RenderTargetHandle.CameraTarget)
                    cmd.GetTemporaryRT(_TemporaryColorTexture.id, renderingData.cameraData.cameraTargetDescriptor, FilterMode.Point);
                    cmd.Blit(_Source, _TemporaryColorTexture.Identifier());
                    cmd.Blit(_TemporaryColorTexture.Identifier(), _Source, _CustomRPSettings.m_Material);
                    cmd.Blit(_Source, _Destination.Identifier(), _CustomRPSettings.m_Material, 0);
                context.ExecuteCommandBuffer(cmd);
                CommandBufferPool.Release(cmd);
            public override void FrameCleanup(CommandBuffer cmd)
                if (_Destination == RenderTargetHandle.CameraTarget)
                    cmd.ReleaseTemporaryRT(_TemporaryColorTexture.id);
        [System.Serializable
    
    
    
    
        
    ]
        public class CustomRPSettings
            public Material m_Material;
        public CustomRPSettings m_CustomRPSettings = new CustomRPSettings();
        CustomRenderPass _ScriptablePass;
        public override void Create()
            _ScriptablePass = new CustomRenderPass(m_CustomRPSettings);
            _ScriptablePass.renderPassEvent = RenderPassEvent.AfterRenderingOpaques;
        public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData)
            _ScriptablePass.Setup(renderer.cameraColorTarget, RenderTargetHandle.CameraTarget);
            renderer.EnqueuePass(_ScriptablePass);
    

    你可以通过单击 “Create > Rendering > Universal Render Pipeline > Renderer Feature” 来创建一个 ScriptableRendererFeature。你创建的功能必须添加到你的中 ForwardRenderer。为此,选择 ForwardRenderer,单击 Add Renderer Feature,然后选择要添加的功能。你可以在 Inspector 中公开属性,例如上面的例子中包含了一个材质球属性。

  • 私信
     1,320