返回

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

变体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(typename) ZERO_INITIALIZE(typename)

阴影贴图

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

内置管线 URP
UNITY_DECLARE_SHADOWMAPtex TEXTURE2D_SHADOW_PARAMtextureNamesamplerName
UNITY_SAMPLE_SHADOWtexuv SAMPLE_TEXTURE2D_SHADOWtextureNamesamplerNamecoord3
UNITY_SAMPLE_SHADOW_PROJtexuv SAMPLE_TEXTURE2D_SHADOWtextureNamesamplerNamecoord4.xyz/coord4.w

纹理/采样器声明宏

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

内置管线 URP
UNITY_DECLARE_TEX2Dname TEXTURE2DtextureName); SAMPLERsamplerName);
UNITY_DECLARE_TEX2D_NOSAMPLERname TEXTURE2DtextureName);
UNITY_DECLARE_TEX2DARRAYname TEXTURE2D_ARRAYtextureName); SAMPLERsamplerName);
UNITY_SAMPLE_TEX2Dnameuv SAMPLE_TEXTURE2DtextureNamesamplerNamecoord2
UNITY_SAMPLE_TEX2D_SAMPLERnamesamplernameuv SAMPLE_TEXTURE2DtextureNamesamplerNamecoord2
UNITY_SAMPLE_TEX2DARRAYnameuv SAMPLE_TEXTURE2D_ARRAYtextureNamesamplerNamecoord2index
UNITY_SAMPLE_TEX2DARRAY_LODnameuvlod SAMPLE_TEXTURE2D_ARRAY_LODtextureNamesamplerNamecoord2indexlod

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

Shader辅助函数

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

顶点转换函数

内置管线 URP
float4 UnityObjectToClipPosfloat3 pos float4 TransformObjectToHClipfloat3 positionOS
float3 UnityObjectToViewPosfloat3 pos TransformWorldToViewTransformObjectToWorldpositionOS))

通用辅助函数

内置管线 URP
float3 WorldSpaceViewDirfloat4 v float3 GetWorldSpaceViewDirfloat3 positionWS Include “Packages/com.unity.render-pipelines.universal/ShaderLibrary/ShaderVariablesFunctions.hlsl”
float3 ObjSpaceViewDirfloat4 v 移除了,可以使用TransformWorldToObject(GetCameraPositionWS()) - objectSpacePosition ;
float2 ParallaxOffsethalf hhalf heighthalf3 viewDir 移除了。可以从UnityCG.cginc复制过来
fixed Luminancefixed3 c real Luminancereal3 linearRgb Include “Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl”
fixed3 DecodeLightmapfixed4 color real3 DecodeLightmap(real4 encodedIlluminance, real4 decodeInstructions) Include “Packages/com.unity.render-pipelines.core/ShaderLibrary/EntityLighting.hlsl” URP中的decodeInstructionshalf4(LIGHTMAP_HDR_MULTIPLIER, LIGHTMAP_HDR_EXPONENT, 0.0h, 0.0h)
float4 EncodeFloatRGBAfloat v 移除了。可以从UnityCG.cginc复制过来
float DecodeFloatRGBAfloat4 enc 移除了。可以从UnityCG.cginc复制过来
float2 EncodeFloatRGfloat v 移除了。可以从UnityCG.cginc复制过来
float DecodeFloatRGfloat2 enc 移除了。可以从UnityCG.cginc复制过来
float2 EncodeViewNormalStereofloat3 n 移除了。可以从UnityCG.cginc复制过来
float3 DecodeViewNormalStereofloat4 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 ComputeScreenPosfloat4 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_4LightPosX0unity_4LightPosY0unity_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_COORDSx 移除了。DIY,例如float4 shadowCoord : TEXCOORD0;
TRANSFER_SHADOWa a.shadowCoord = TransformWorldToShadowCoordworldSpacePosition 启用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
LinearEyeDepthsceneZ LinearEyeDepthsceneZ_ZBufferParams Include “Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl”
Linear01DepthsceneZ Linear01DepthsceneZ_ZBufferParams Include “Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl”

其他中的其他

内置管线 URP
ShadeSH9normal SampleSHnormal 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中公开属性,例如上面的例子中包含了一个材质球属性。

com.unity.render-pipelines.universal

Core.hlsl
名称 说明
GetVertexPositionInputs(float3 positionOS) 获取输入顶点坐标信息
GetVertexNormalInputs(float3 normalOS) 获取输入顶点法线信息
GetVertexNormalInputs(float3 normalOS, float4 tangentOS) 获取输入顶点法线信息(重载)
GetScaledScreenParams() 获取屏幕缩放参数信息
NormalizeNormalPerVertex(real3 normalWS) 逐顶点法线正交
NormalizeNormalPerPixel(real3 normalWS) 逐像素法线正交
ComputeScreenPos(float4 positionCS) 计算屏幕坐标信息
(real)ComputeFogFactor(float z) 计算雾参数
(real)ComputeFogIntensity(real fogFactor) 计算雾强度
(half3)MixFogColor(real3 fragColor, real3 fogColor, real fogFactor) 混合雾颜色
(half3)MixFog(real3 fragColor, real fogFactor) 混合雾
Lighting.hlsl
名称 说明
DistanceAttenuation(float distanceSqr, half2 distanceAttenuation) 距离衰减
AngleAttenuation(half3 spotDirection, half3 lightDirection, half2 spotAttenuation) 角度衰减
GetMainLight()/GetMainLight(float4 shadowCoord) 获取主光源
GetPerObjectLightIndex(int index) 获取每个对象灯光Index
GetAdditionalLightsCount() 获取额外灯光数量
ReflectivitySpecular(half3 specular) 高光反射率
OneMinusReflectivityMetallic(half metallic) OneMinus金属反射率
InitializeBRDFData(half3 albedo, half metallic, half3 specular, half smoothness, half alpha, out BRDFData outBRDFData) 初始化BRDF
EnvironmentBRDF(BRDFData brdfData, half3 indirectDiffuse, half3 indirectSpecular, half fresnelTerm) 环境BRDF
DirectBDRF(BRDFData brdfData, half3 normalWS, half3 lightDirectionWS, half3 viewDirectionWS) BRDF
SampleLightmap(float2 lightmapUV, half3 normalWS) 光照贴图
GlossyEnvironmentReflection(half3 reflectVector, half perceptualRoughness, half occlusion) 环境光泽反射
GlobalIllumination(BRDFData brdfData, half3 bakedGI, half occlusion, half3 normalWS, half3 viewDirectionWS) 全局光照
MixRealtimeAndBakedGI(inout Light light, half3 normalWS, inout half3 bakedGI, half4 shadowMask) 实时烘培混合
LightingLambert(half3 lightColor, half3 lightDir, half3 normal) 兰伯特模型
LightingSpecular(half3 lightColor, half3 lightDir, half3 normal, half3 viewDir, half4 specular, half smoothness) 高光
LightingPhysicallyBased(BRDFData brdfData, half3 lightColor, half3 lightDirectionWS, half lightAttenuation, half3 normalWS, half3 viewDirectionWS)/LightingPhysicallyBased(BRDFData brdfData, Light light, half3 normalWS, half3 viewDirectionWS) 基于物理的光照模型
VertexLighting(float3 positionWS, half3 normalWS) 顶点光照颜色
LightweightFragmentPBR(InputData inputData, half3 albedo, half metallic, half3 specular,half smoothness, half occlusion, half3 emission, half alpha) 轻量级片元PBR
LightweightFragmentBlinnPhong(InputData inputData, half3 diffuse, half4 specularGloss, half smoothness, half3 emission, half alpha) 轻量级片元布林·冯
Shadows.hlsl
名称 说明
GetMainLightShadowStrength() 获取主光源阴影强度
GetAdditionalLightShadowStrenth(int lightIndex) 获取额外光源阴影强度
SampleScreenSpaceShadowmap(float4 shadowCoord) 屏幕空间阴影贴图
SampleShadowmap(float4 shadowCoord, TEXTURE2D_SHADOW_PARAM(ShadowMap, sampler_ShadowMap), ShadowSamplingData samplingData, half shadowStrength, bool isPerspectiveProjection = true) 阴影贴图
TransformWorldToShadowCoord(float3 positionWS) 把顶点的世界坐标转换到阴影坐标
MainLightRealtimeShadow(float4 shadowCoord) 主光源实时阴影
AdditionalLightRealtimeShadow(int lightIndex, float3 positionWS) 额外光源实时阴影
GetShadowCoord(VertexPositionInputs vertexInput) 获取阴影坐标信息
ApplyShadowBias(float3 positionWS, float3 normalWS, float3 lightDirection) 应用阴影偏移

com.unity.render-pipelines.core

SpaceTransforms.hlsl

变换矩阵:

名称 说明
TransformObjectToWorld(float3 positionOS) 当前模型空间转世界空间矩阵,通常用于把顶点/方向矢量从模型空间转到世界空间
TransformWorldToObject(float3 positionWS) 当前世界空间转模型空间矩阵,通常用于把顶点/方向矢量从世界空间转到模型空间
TransformWorldToView(float3 positionWS) 当前世界空间转相机空间矩阵,通常用于把顶点/方向矢量从世界空间转到相机空间
TransformObjectToHClip(float3 positionOS) 当前模型空间转裁剪空间矩阵,通常用于把顶点/方向矢量从模型空间转到裁剪空间
TransformWorldToHClip(float3 positionWS) 当前世界空间转裁剪空间矩阵,通常用于把顶点/方向矢量从世界空间转到裁剪空间
TransformWViewToHClip(float3 positionVS) 当前相机空间转裁剪空间矩阵,通常用于把顶点/方向矢量从相机空间转到裁剪空间
TransformObjectToWorldDir(real3 dirOS) 把方向矢量从模型空间转换到世界空间中
TransformWorldToObjectDir(real3 dirWS) 把方向矢量从世界空间转换到模型空间中
TransformWorldToViewDir(real3 dirWS) 把方向矢量从世界空间转换到相机空间中
TransformWorldToHClipDir(real3 directionWS) 把方向矢量从世界空间转换到裁剪空间中
TransformObjectToWorldNormal(float3 normalOS) 把法线从模型空间转换到世界空间中
CreateTangentToWorld(real3 normal, real3 tangent, real flipSign) 创建一个切线空间转为世界空间的3x3矩阵
TransformTangentToWorld(real3 dirTS, real3x3 tangentToWorld) 当前切线空间转世界空间矩阵,通常用于把顶点/方向矢量从切线空间转到世界空间
TransformWorldToTangent(real3 dirWS, real3x3 tangentToWorld) 当前世界空间转切线空间矩阵,通常用于把顶点/方向矢量从世界空间转到切线空间
TransformTangentToObject(real3 dirTS, real3x3 tangentToWorld) 当前切线空间转模型空间矩阵,通常用于把顶点/方向矢量从切线空间转到模型空间
Licensed under CC BY-NC-SA 4.0
0