目录
5.预处理宏 Predefined Shader Preprocessor Macros
这里的大部分内容基于 7.3 版 ,有可能新版本会发生变化,请留意最新文档!
Unity 的 可编程渲染管线(Scriptable Render Pipeline) 代表了Unity处理图形方式的一大进步,为用户提供了更多定制管线的能力,我已经开始使用通用管线 (Universal Render Pipeline) 但仍然缺文档,你可以找到包含每个可用函数的信息,但仍然难找到 重Built-in 到 URP 的示例。
本文提供重 Built-in 到 URP 的示例总结,希望可以帮助到大家
1.开始之前这里有一些链接可以帮助你深入了解URP
Outline post-effect using ScriptableRendererFeature
1.总体结构
首先添加 "RenderPipeline" = "UniversalPipeline" 到Tag 下一步 所有的URP shader 都是使用HLSLPROGRAM/ENDHLSL/etc. 包含的HLSL 编写
Built-in | URP |
CGPROGRAM | HLSLPROGRAM |
ENDCG | ENDHLSL |
CGINCLUDE | HLSLINCLUDE |
2.Shader Include 头文件
Content | Built-in | 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 |
Shadows | AutoLight.cginc | Packages/com.unity.render-pipelines.universal/ShaderLibrary/Shadows.hlsl |
Surface shaders | Lighting.cginc | 没有 ,但这个链接可以找到一个辅助项目 here |
其他有用的包括
- 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
3.灯光模式
Built-in | URP |
ForwardBase | UniversalForward |
ForwardAdd | 无 |
Deferred and related | |
Vertex and related | 无 |
ShadowCaster | ShadowCaster |
MotionVectors | 暂不支持 |
支持的其他照明模式包括
1.DepthOnly
2. Meta (用于烘焙光照贴图)
3.Universal2D
4.变种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
5.预处理宏 Predefined Shader Preprocessor Macros
5.1辅助函数
Built-in | URP |
UNITY_PROJ_COORD(a) | Gone. Do a.xy/a.w instead |
UNITY_INITIALIZE_OUTPUT(type, name) | ZERO_INITIALIZE(type, name) |
5.2阴影贴图
你必须包含 #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Shadows.hlsl"
Built-in | 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) |
5.3贴图/采样器 声明宏
Unity 有很多纹理/采样器 用来兼容不同平台 ,这些仍然处理URP 中,但现在有了不同的名称和
新添加的,由于数量很多这里不会全部列出,你可以针对不同API平台查看他们的具体定义 API includes.
Built-in | 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 (单通道/立体渲染)下的屏幕空间的特效
你必须用TEXTURE2D_X 声明 ,此宏将正确的处理纹理(是否为数组),还必须使用 SAMPLE_TEXTURE2D_X 采样贴图,UV 使用
UnityStereoTransformScreenSpaceTex
6.内置的shader 辅助函数
你需要包含
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/SpaceTransforms.hlsl"
6.1顶点变换函数
Built-in | URP |
float4 UnityObjectToClipPos(float3 pos) | float4 TransformObjectToHClip(float3 positionOS) |
float3 UnityObjectToViewPos(float3 pos) | TransformWorldToView(TransformObjectToWorld(positionOS)) |
6.2通用辅助函数
Built-in | URP |
|
float3 WorldSpaceViewDir (float4 v) | float3 GetWorldSpaceViewDir(float3 positionWS) | Include “Packages/com.unity.render-pipelines.universal/ShaderLibrary/ShaderVariablesFunctions.hlsl” |
float3 ObjSpaceViewDir (float4 v) | Gone. Do 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” |
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 拷贝 |
6.3前向渲染辅助函数
Built-in | 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) | For VertexLighting(...) include “Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl” |
6.4屏幕空间辅助函数
Built-in | URP |
|
float4 ComputeScreenPos (float4 clipPos) | float4 ComputeScreenPos(float4 positionCS) | Include “Packages/com.unity.render-pipelines.universal/ShaderLibrary/ShaderVariablesFunctions.hlsl” |
float4 ComputeGrabScreenPos (float4 clipPos) | 无. |
6.5顶点光照辅助函数
Built-in | URP |
|
float3 ShadeVertexLights (float4 vertex, float3 normal) | 无.你可以尝试这个 UNITY_LIGHTMODEL_AMBIENT.xyz + VertexLighting(...) | For VertexLighting(...) include “Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl” |
公用的函数可以在这里找到
7.内置shader 变体
“Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl”.
除了灯光 大多数的shader 变量保持不变
7.1灯光
Built-in | 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 | 无? 尚未支持烘焙 | |
unity_4LightPosX0, unity_4LightPosY0, unity_4LightPosZ0 | 在URP 中,其他的光源储存在数组 Array/缓冲区Buffer 中(取决于平台). 检索灯光信息 | Include “Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl” |
unity_4LightAtten0 | 在URP 中,其他的光源储存在数组 Array/缓冲区Buffer 中(取决于平台). 检索灯光信息 | Include “Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl” |
unity_LightColor | 在URP 中,其他的光源储存在数组 Array/缓冲区Buffer 中(取决于平台). 检索灯光信息 | 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()
8.杂项
8.1shadow
有关阴影的更多信息请查看
“Packages/com.unity.render-pipelines.universal/ShaderLibrary/Shadows.hlsl”.
Built-in | URP |
|
UNITY_SHADOW_COORDS(x) | 无? 自定义一个. float4 shadowCoord : TEXCOORD0; | |
TRANSFER_SHADOW(a) | a.shadowCoord = TransformWorldToShadowCoord(worldSpacePosition) | 当启用级联时(CSM ) 在片段着色器应用防止伪影 |
SHADOWS_SCREEN | 无. 不支持. |
8.2雾Fog
更多雾相关的请查看此文件 “Packages/com.unity.render-pipelines.universal/ShaderLibrary/ShaderVariablesFunctions.hlsl”.
8.3深度Depth
要使用相机深度请包含 “Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareDepthTexture.hlsl”
你还需要声明 _CameraDepthTexture 及帮助函数 SampleSceneDepth(...) 和LoadSceneDepth(...).
Built-in | 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” |
8.4其他
Built-in | 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” |
9.后处理/VFX (视觉特效)
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)
用法示例
void OnEnable()
{
RenderPipelineManager.beginCameraRendering += MyCameraRendering;
}
void OnDisable()
{
RenderPipelineManager.beginCameraRendering -= MyCameraRendering;
}
void MyCameraRendering(ScriptableRenderContext context, Camera camera)
{
...
if(camera == myEffectCamera)
{
...
}
...
}
虽然支持OnWillRenderObject,但是,如果您需要在其中执行渲染调用(例如,水反射/折射),它就无法正常工作。
在这种情况下,用begin / endCameraRendering(如上面的示例)替换OnWillRenderObject,然后从URP而不是Camera.Render()中调用RenderSingleCamera()。更改上面的示例
void MyCameraRendering(ScriptableRenderContext context, Camera camera)
{
...
if(camera == myEffectCamera)
{
...
UniversalRenderPipeline.RenderSingleCamera(context, camera);
}
...
}
使用后处理的另一种方法是使用ScriptableRendererFeature。这篇文章很好地解释了使用此功能的描边效果。
A 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 并选择你要添加的功能,
例如如果你使用了上面的示例代码 ,可以看到一个可用的材质槽