首页 > 其他分享 >内置管线Shader升级到URP详细手册

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

时间:2022-08-30 08:59:06浏览次数:108  
标签:内置 pipelines render Shader unity URP ShaderLibrary com

目录

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

前言

本文初版内容翻译自:

https://teodutra.com/unity/shaders/urp/graphics/2020/05/18/From-Built-in-to-URP/

在开始之前,这里有一些有用的链接可以帮助深入了解URP内容:


总体结构

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

内置管线 URP
CGPROGRAM/HLSLPROGRAM HLSLPROGRAM
ENDCG/ENDHLSL ENDHLSL
CGINCLUDE/HLSLINCLUDE HLSLINCLUDE

Include文件

内容 内置管线 URP
Core Unity.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内没有,可参考项目:在此处

其他有用的包括:

灯光模式LightMode

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

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

  • DepthOnly

  • Meta (for lightmap baking)

  • Universal2D

  • UniversalGBuffer

  • UniversalForwardOnly

  • DepthNormalsOnly

  • SRPDefaultUnlit

新增的照明模式详情:在此处

变体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)

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 备注
float3 WorldSpaceViewDir (float4 v) float3 GetWorldSpaceViewDir(float3 positionWS) Include “Packages/com.unity.render-pipelines.universal/ShaderLibrary/ShaderVariablesFunctions.hlsl
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.hlslURP中用的decodeInstructionshalf4(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复制过来

前向渲染辅助函数

内置管线 URP 备注
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) - 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(...) includePackages/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不支持OnPreCullOnPreRenderOnPostRenderOnRenderImage这些方法。URP支持OnRenderObjectOnWillRenderObject,但是如果在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);
            }
            else
            {
                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中公开属性,例如上面的例子中包含了一个材质球属性。

标签:内置,pipelines,render,Shader,unity,URP,ShaderLibrary,com
From: https://www.cnblogs.com/kexiaohao/p/16638070.html

相关文章