内置管线 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文件
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
|
|
|
前向渲染辅助函数
屏幕空间辅助函数
顶点照明辅助函数
↑
可以在
“Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.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 不支持
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 中公开属性,例如上面的例子中包含了一个材质球属性。
- 3145
-
ShaderJoy
JavaScript