1. 程式人生 > 其它 >Unity Built-in轉URP速查表

Unity Built-in轉URP速查表

轉載自

https://cuihongzhi1991.github.io/blog/2020/05/27/builtinttourp/

本篇文章轉自Teofilo Dutra編寫的《From Built-in to URP》,其中有很多在寫URP管線Shader時需要用到的函式,作為備忘速查表非常實用,所以記錄於此。本文經過精簡和翻譯,不一定適用於大家,可以點選上方連結跳轉至作者原文。本文是基於7.3版本的URP編寫的,有些暫時還不支援的內容可能在後續版本更新迭代。

結構

首先要在SubShader的Tags中新增”RenderPipeline” = “UniversalPipeline”,並且使用HLSL的巨集代替舊版的CG語言巨集。

Built-inURP
CGPROGRAM / HLSLPROGRAM HLSLPROGRAM
ENDCG / ENDHLSL ENDHLSL
CGINCLUDE / HLSLINCLUDE HLSLINCLUDE

Include檔案的改動

ContentBuilt-inURP
Core Unity.cginc Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl
Light AutoLight.cginc Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl
Shadows AutoLight.cginc Packages/com.unity.render-pipelines.universal/ShaderLibrary/Shadows.hlsl
Surface shaders Lighting.cginc

其他常用的include檔案:

  • 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

光照模式

Built-inURP
ForwardBase UniversalForward
ForwardAdd
Deferred and related UniversalGBuffer seems to have just been added to URP
Vertex and related
ShadowCaster ShadowCaster
MotionVectors 暫不支援

URP其他支援的光照模式:

  • DepthOnly
  • Meta (用於烘焙光照貼圖)
  • 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

預定義的著色器預處理巨集

輔助巨集(Helpers)

Built-inURP
UNITY_PROJ_COORD(a) 無,使用 a.xy/a.w 來代替
UNITY_INITIALIZE_OUTPUT(type, name) ZERO_INITIALIZE(type, name)

陰影貼圖

需要包含 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)

紋理/取樣器的宣告巨集

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)

內建的著色器輔助函式

可以在 Packages/com.unity.render-pipelines.core/ShaderLibrary/SpaceTransforms.hlsl 看到下方的所有函式

頂點變換函式

Built-inURP
float4 UnityObjectToClipPos(float3 pos) float4 TransformObjectToHClip(float3 positionOS)
float3 UnityObjectToViewPos(float3 pos) TransformWorldToView(TransformObjectToWorld(positionOS))

泛用的輔助函式

Built-inURPInclude
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.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-inURPInclude
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) include “Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl”

螢幕空間輔助函式

Built-inURPInclude
float4 ComputeScreenPos (float4 clipPos) float4 ComputeScreenPos(float4 positionCS) Include “Packages/com.unity.render-pipelines.universal/ShaderLibrary/ShaderVariablesFunctions.hlsl”
float4 ComputeGrabScreenPos (float4 clipPos)

頂點光照的輔助函式

Built-inURPInclude
float3 ShadeVertexLights (float4 vertex, float3 normal) 無,可嘗試用 UNITY_LIGHTMODEL_AMBIENT.xyz + VertexLighting(…) include “Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl”

可以在 Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl 中找到一些通用函式

內建的著色器變數

Built-inURPInclude
_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 可能還不支援
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] or _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

Built-inURP
UNITY_SHADOW_COORDS(x) 可能沒有,可以寫作float4 shadowCoord : TEXCOORD0;
TRANSFER_SHADOW(a) a.shadowCoord = TransformWorldToShadowCoord(worldSpacePosition)
SHADOWS_SCREEN 暫不支援

更多霧相關的函式可以檢視 Packages/com.unity.render-pipelines.universal/ShaderLibrary/ShaderVariablesFunctions.hlsl

Built-inURP
UNITY_FOG_COORDS(x) 可能沒有,可以寫作float fogCoord : TEXCOORD0;
UNITY_TRANSFER_FOG(o, outpos) o.fogCoord = ComputeFogFactor(clipSpacePosition.z);
UNITY_APPLY_FOG(coord, col) color = MixFog(color, i.fogCoord);

深度

可以包含 “Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareDepthTexture.hlsl” 並使用 _CameraDepthTexture來呼叫深度紋理。也可以使用SampleSceneDepth(…) 和 LoadSceneDepth(…)。

Built-inURPInclude
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-inURPInclude
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. 支援 OnRenderObject 和 OnWillRenderObject。RenderPipelineManager提供了渲染管線中注入的位置:

  • beginCameraRendering(ScriptableRenderContext context, Camera camera)
  • endCameraRendering(ScriptableRenderContext context, Camera camera)
  • beginFrameRendering(ScriptableRenderContext context,Camera[] cameras)
  • endFrameRendering(ScriptableRenderContext context,Camera[] cameras)

例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
void OnEnable()
{
RenderPipelineManager.beginCameraRendering += MyCameraRendering;
}

void OnDisable()
{
RenderPipelineManager.beginCameraRendering -= MyCameraRendering;
}

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


另外,可以建立ScriptableRendererFeature來實現後期處理效果。可以在管線的不同階段注入ScriptableRenderPasses:

  • BeforeRendering
  • BeforeRenderingShadows
  • AfterRenderingShadows
  • BeforeRenderingPrepasses
  • AfterRenderingPrePasses
  • BeforeRenderingOpaques
  • AfterRenderingOpaques
  • BeforeRenderingSkybox
  • AfterRenderingSkybox
  • BeforeRenderingTransparents
  • AfterRenderingTransparents
  • BeforeRenderingPostProcessing
  • AfterRenderingPostProcessing
  • AfterRendering

下面是一個示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
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);
}
}