unity渲染管线及升级URP 一,unity渲染管线简介 二,通用渲染管线URP 三,shader升级URP 1,Builtin RP和URP中内置Shader 的对应 2,总体结构 3,include 4,光照模式LightMode 5,变体Variants 6,预定义宏 7,辅助函数 变换函数 通用辅助函数 向前渲染函数 屏幕空间 顶点光照 深度 其他 7,内置变量 8,后处理 参考资料
22.5.31 发现这篇只能查找参考用,实际改urp看了用处不大,urp管线下pbrshader流程看新写的URP实现PBR shader吧
一,unity渲染管线简介
Unity引擎的渲染管线主要分为"渲染核心库"与"渲染策略"两个部分, “渲染核心库”是Unity把基于OpenGL/DirectX把渲染相关的接口函数封装成API,这部分Unity引擎写好后作为核心的API渲染库。”渲染策略”指的是Unity引擎绘制整个游戏场景的时候,如何处理多相机,多光源,阴影投射,物体绘制,雾,自发光等。这个就叫做渲染策略,渲染管线基于一种渲染策略,调用渲染核心库中的API,把整个游戏场景绘制出来。
渲染管线通过执行 剔除、渲染、后处理 来获取场景的内容,并将这些内容显示在屏幕上。不同的渲染管线具有不同的功能和性能特征,并且适用于不同的游戏、应用程序和平台。
unity提供三种渲染管线,内置渲染管线、通用渲染管线(URP)和高清渲染管线(HDRP),也可以通过unity的可编程渲染管线(Scriptable Render Pipeline,SRP) API 来完全自定义渲染管线。 内置渲染管线是unity默认的,自定义选项有限,是向前渲染(支持任意多光源,每个光照各走一遍pass性能差)。(可以用CommandBuffer和回调进行骚操作,版稳定性不好死板) URP(Universal Render Pipeline)「前身LWRP–轻量级渲染管线」是用SRP写的非侵入式轻量级自定义渲染管线,专注性能,比如只支持几个光源但能在同一个pass计算;除了有特殊需求选它就对了。 HDRP可以做更多复杂算法,可以在高端平台上(PC主机等)输出高保真图形,支持全局光照、光线跟踪、子面散射等,但想得到好效果需要大量贴图,人力预算up!「因为这次主要学习URP,HDRP这里就简单了解下。也有人说HDRP太复杂了,不如直接用ue。」
其主要区别在于渲染策略,不同的渲染策略对应的shader不一样,之前学习的shader写法都是针对向前渲染的,如果切换成URP则shader包需要重新开发。可编程渲染管线shader语法结构还是shader lab,开发语言使用HLSL,有的也支持shader graphic。
二,通用渲染管线URP
三,shader升级URP
1,Builtin RP和URP中内置Shader 的对应
2,总体结构
在SubShader的Tags中添加"RenderPipeline" = “UniversalPipeline"表示该SubShader是给URP用的「HDRP设置为"HDRenderPipeline”」 并使用HLSL的宏替代CG:
Built-in URP CGPROGRAM、HLSLPROGRAM HLSLPROGRAM ENDCG、ENDHLSL ENDHLSL CGINCLUDE、HLSLINCLUDE HLSLINCLUDE
HLSL是URP的首选语言,但URP也支持CG语言,因此CGPROGRAM等也能用,就是和SRP Batcher 不兼容。
在Properties中声明的属性需要再在HLSL 代码中用CBUFFER声明(为了SRP Batcher):
TEXTURE2D(_BaseMap);
SAMPLER(sampler_BaseMap);CBUFFER_START(UnityPerMaterial)half4 _BaseColor;float4 _BaseMap_ST;
CBUFFER_END
fixed都不支持了,改为half或者float。
3,include
\ 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 URP内没有,可以参考该github项目
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
URP其他常用include:SpaceTransforms.hlsl、ShaderVariablesFunctions.hlsl、Common.hlsl、Input.hlsl、Color.hlsl、DeclareDepthTexture.hlsl、DeclareOpaqueTextue.hlsl Core.hlsl可以直接引用,UnityInput.hlsl、UnityInstancing.hlsl、SpaceTransforms.hlsl等需要带上前缀,防止重定义。
4,光照模式LightMode
Built-in URP ForwardBase UniversalForward ForwardAdd 移除,开启关键字_ADDITIONAL_LIGHTS解决 Deferred 以及相关 URP12.0支持 Vertex and related 移除 ShadowCaster ShadowCaster MotionVectors 暂不支持
URP新增的:DepthOnly、Meta(用于烘焙光照贴图)、Universal2D(用于2D的前向渲染)、UniversalGBuffer(延迟渲染用)、UniversalForwardOnly(延迟渲染中表示该pass用向前渲染)。
5,变体Variants
类似内置管线用multi_compile_fwdbase编译ForwardBasePass;URP涉及批处理的变体,可以用#pragma multi_compile添加关键字设置:
#pragma multi_compile _ _MAIN_LIGHT_SHADOWS
#pragma multi_compile _ _MAIN_LIGHT_SHADOWS_CASCADE
#pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS
#pragma multi_compile _ _ADDITIONAL_LIGHT_SHADOWS
#pragma multi_compile _ _SHADOWS_SOFT
#pragma multi_compile _ _MIXED_LIGHTING_SUBTRACTIVE
6,预定义宏
辅助宏
Built-in URP 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-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) UNITY_SHADOW_COORDS(x) float4 shadowCoord : TEXCOORD##x TRANSFER_SHADOW(a) a.shadowCoord = TransformWorldToShadowCoord(worldSpacePosition) SHADOWS_SCREEN 移除了
纹理采样器声明
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) UNITY_INITIALIZE_OUTPUT(name) ZERO_INITIALIZE(name)
光照、雾
Built-in URP UNITY_LIGHTMODEL_AMBIENT half3(unity_SHAr.w,unity_SHAr.w,unity_SHAr.w); UNITY_FOG_COORDS(x) 用float fogCoord : TEXCOORD##x; UNITY_TRANSFER_FOG(o, outpos) o.fogCoord = ComputeFogFactor(clipSpacePosition.z); UNITY_APPLY_FOG(coord, col) color = MixFog(color, i.fogCoord);
7,辅助函数
变换函数
Built-in URP float4 UnityObjectToClipPos(float3 pos) float4 TransformObjectToHClip(float3 positionOS) float4 UnityWorldToClipPos(float3 pos) float4 TransformWorldToHClip(float3 positionWS) float3 UnityObjectToViewPos(float3 pos) TransformWorldToView(TransformObjectToWorld(positionOS)) float3 UnityObjectToWorldNormal(in float3 norm) float3 TransformObjectToWorldNormal(float3 normalOS,bool doNormalize = true) float3 UnityWorldSpaceViewDir (float4 v) _WorldSpaceCameraPos.xyz - positionWS float3 UnityObjectToWorldDir (float4 v) float3 TransformObjectToWorldDir(real3 dirOS)
通用辅助函数
Built-in URP 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) fixed3 DecodeLightmap (fixed4 color) real3 DecodeLightmap(real4 encodedIlluminance, real4 decodeInstructions) 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-in URP float3 WorldSpaceLightDir(float4 v) _MainLightPosition.xyz - TransformObjectToWorld(objectSpacePosition) float3 ObjSpaceLightDir (float4 v) TransformWorldToObject(_MainLightPosition.xyz) - objectSpacePosition float3 Shade4PointLights (…) 用half3 VertexLighting(float3 positionWS, half3 normalWS)
屏幕空间
Built-in URP float4 ComputeScreenPos (float4 clipPos) float4 ComputeScreenPos(float4 positionCS) float4 ComputeGrabScreenPos (float4 clipPos) 移除了
顶点光照
Built-in URP float3 ShadeVertexLights (float4 vertex, float3 normal) 用half3(unity_SHAr.w, unity_SHAg.w, unity_SHAb.w) + VertexLighting(…)
深度
可直接使用 _CameraDepthTexture来采样深度纹理,也可使用SampleSceneDepth(…) 和 LoadSceneDepth(…)来采样。
Built-in URP LinearEyeDepth (sceneZ) LinearEyeDepth(sceneZ, _ZBufferParams) Linear01Depth (sceneZ) Linear01Depth(sceneZ, _ZBufferParams)
其他
Built-in URP shadeSH9 (float4 normal) SampleSH(normal) unity_ColorSpaceLuminance 用Luminance()
7,内置变量
Built-in URP _LightColor0 _MainLightColor _WorldSpaceLightPos0 _MainLightPosition _LightMatrix0 移除了。目前尚不支持 unity_4LightPosX0, unity_4LightPosY0, unity_4LightPosZ0 在URP中,其他光源存储在数组/缓冲区中(取决于平台)。使用Light GetAdditionalLight(uint i, float3 positionWS)获取光源信息 unity_4LightAtten0 同上 unity_LightColor 同上) unity_WorldToShadow float4x4 _MainLightWorldToShadow[MAX_SHADOW_CASCADES + 1] 或者_AdditionalLightsWorldToShadow[MAX_VISIBLE_LIGHTS]
使用循环所有其他灯光–GetAdditionalLight(),查询其他灯光计数–GetAdditionalLightsCount()。
8,后处理
URP不支持OnPreCull,OnPreRender,OnPostRender和OnRenderImage。 支持OnRenderObject和OnWillRenderObject,但旧管线直接用有问题,需要改写。 UPR函数+示例:
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) { . . . UniversalRenderPipeline. RenderSingleCamera ( context, camera) ; } . . .
}
参考资料
unity官方文档 知乎-Unity URP/SRP 渲染管线浅入深出 From Built-in to URP 内置到URP官方切换文档