本篇文章轉自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);}
}
總結
以上是生活随笔 為你收集整理的Unity Built-in Shader转URP Shader 接口查询对照表 的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔 網站內容還不錯,歡迎將生活随笔 推薦給好友。