GameTech/URP 渲染实战
APPENDIX附录

附录:速查表

写 Shader、查问题时最常翻的几张表:URP 14 ShaderLibrary 函数签名、内置变量与宏、LightMode 与关键字、Built-in 迁移对照、中英术语和延伸阅读。所有签名和名字都对照 URP 14.0.12 / Core 14.0.12 的源码逐条核对过。

怎么用这份附录签名按“源码原样”抄录(只把多行参数并成一行),所以你看到的 real、half、默认参数都和源码一致。real 是 Core 定义的精度别名:在支持半精度的移动平台上可能是 half,否则是 float。路径简写:URP/ 指 Packages/com.unity.render-pipelines.universal/ShaderLibrary/,Core/ 指 Packages/com.unity.render-pipelines.core/ShaderLibrary/。版本升级后签名可能变,以你工程 Library/PackageCache 里的实际源码为准。

A. URP ShaderLibrary 常用函数速查

先看 include 关系。手写 URP Shader 通常只需要两行:Core.hlsl 负责变换、输入变量和基础工具;要算光照再加 Lighting.hlsl。下表列出它们各自“顺带”拉进来的文件,免得你重复 include 或者漏掉。

你 include 的文件它会间接引入
URP/Core.hlslCore/Common.hlsl(含 Macros.hlsl、平台 API 宏)、Core/Packing.hlsl、URP/Input.hlsl(→ UnityInput.hlsl、Core/UnityInstancing.hlsl、Core/SpaceTransforms.hlsl)、URP/ShaderVariablesFunctions.hlsl(→ Debug/DebuggingCommon.hlsl → Core/Color.hlsl)
URP/Lighting.hlslBRDF.hlsl(→ Core/BSDF.hlsl、Core/CommonMaterial.hlsl、SurfaceData.hlsl)、GlobalIllumination.hlsl(→ Core/EntityLighting.hlsl、Core/ImageBasedLighting.hlsl)、RealtimeLights.hlsl(→ Shadows.hlsl、LightCookie/LightCookie.hlsl、Clustering.hlsl)、AmbientOcclusion.hlsl、DBuffer.hlsl
URP/SurfaceInput.hlslCore.hlsl、SurfaceData.hlsl、Core/Packing.hlsl、Core/CommonMaterial.hlsl;并且声明了 _BaseMap、_BumpMap、_EmissionMap 及其采样器
URP/DeclareDepthTexture.hlsl 等三个 Declare 文件Core.hlsl,并声明 _CameraDepthTexture / _CameraNormalsTexture / _CameraOpaqueTexture
Core/…/Runtime/Utilities/Blit.hlslCommon.hlsl、Color.hlsl、UnityInstancing.hlsl、GlobalSamplers.hlsl、EntityLighting.hlsl(完整路径 Packages/com.unity.render-pipelines.core/Runtime/Utilities/Blit.hlsl)
注意包含了 SurfaceInput.hlsl 就不要再自己写 TEXTURE2D(_BaseMap),否则会重定义报错。自己的 Shader 想用别的名字(如 _MainTex)就别 include 它,需要的函数自己写或照抄。

A.1 ShaderVariablesFunctions.hlsl(URP,由 Core.hlsl 引入)

签名说明
VertexPositionInputs GetVertexPositionInputs(float3 positionOS)一次算出 positionWS / positionVS / positionCS / positionNDC。NDC 的 xy 范围是 [0, w],除以 w 才是 0~1 屏幕坐标。
VertexNormalInputs GetVertexNormalInputs(float3 normalOS)只变换法线到世界空间,切线、副切线填默认值 (1,0,0)/(0,1,0)。
VertexNormalInputs GetVertexNormalInputs(float3 normalOS, float4 tangentOS)得到世界空间 TBN;副切线已乘 tangentOS.w 和 GetOddNegativeScale(),不在此处归一化。
float4 GetScaledScreenParams()返回 _ScaledScreenParams,即考虑 Render Scale 之后的渲染分辨率。
bool IsPerspectiveProjection()透视相机返回 true(判断 unity_OrthoParams.w == 0)。
float3 GetCameraPositionWS()相机世界坐标,目前直接返回 _WorldSpaceCameraPos。
float3 GetCurrentViewPosition()当前视点位置,URP 14 中等同 GetCameraPositionWS()。
float3 GetViewForwardDir()当前视图在世界空间的前向(相机看向的方向)。
float3 GetWorldSpaceViewDir(float3 positionWS)从表面指向相机的向量,未归一化;正交相机返回 -GetViewForwardDir()。
half3 GetWorldSpaceNormalizeViewDir(float3 positionWS)同上但已归一化,最常用的 V 向量。
half3 GetObjectSpaceNormalizeViewDir(float3 positionOS)模型空间的归一化视线方向。
void GetLeftHandedViewSpaceMatrices(out float4x4 viewMatrix, out float4x4 projMatrix)把右手系视图矩阵的 Z 翻转成“向前为正”的左手系版本,同时修正投影矩阵。
bool IsSurfaceTypeOpaque(half surfaceType)与材质 _Surface 属性约定一致:0 为不透明。
bool IsSurfaceTypeTransparent(half surfaceType)1 为透明。
half AlphaClip(half alpha, half cutoff)Alpha 裁剪,支持 Alpha To Coverage。只在定义了 _ALPHATEST_ON 时存在。
half SharpenAlphaStrict(half alpha, half alphaClipTreshold)为 Alpha To Coverage 锐化 alpha(同样只在 _ALPHATEST_ON 下存在)。
real AlphaDiscard(real alpha, real cutoff, real offset = real(0.0))常用的裁剪入口:有 _ALPHATEST_ON 才真正 clip,否则原样返回 alpha。
half OutputAlpha(half alpha, bool isTransparent)不透明物体输出 1,透明物体输出原 alpha。
half3 AlphaModulate(half3 albedo, half alpha)_ALPHAMODULATE_ON 时把颜色向白色插值,用于 Multiply 混合。
half3 AlphaPremultiply(half3 albedo, half alpha)_ALPHAPREMULTIPLY_ON 时把 alpha 乘进颜色。
half3 NormalizeNormalPerVertex(half3 normalWS)顶点阶段归一化法线(另有 float3 重载)。
half3 NormalizeNormalPerPixel(half3 normalWS)片元阶段归一化法线,XYZ 法线编码 + 法线贴图时用 SafeNormalize(另有 float3 重载)。
real ComputeFogFactor(float zPositionCS)顶点阶段由裁剪空间 z 计算雾因子,存进插值器。
real ComputeFogFactorZ0ToFar(float z)由 [0, far] 范围的视距算雾因子(线性 / 指数 / 指数平方三种模式)。
real InitializeInputDataFog(float4 positionWS, real vertFogFactor)片元阶段按视距重新计算雾因子。文件里 _FOG_FRAGMENT 被强制定义为 1,所以 URP 14 的雾实际按像素计算。
half ComputeFogIntensity(half fogFactor)把雾因子换算成 0~1 的“保留原色比例”(另有 float 重载)。
half3 MixFog(half3 fragColor, half fogFactor)用场景雾色 unity_FogColor 混合(另有 float3 重载)。
half3 MixFogColor(half3 fragColor, half3 fogColor, half fogFactor)用自定义雾色混合,适合 Additive 物体传黑色雾色(另有 float3 重载)。
float LinearDepthToEyeDepth(float rawDepth)正交相机的深度缓冲本身是线性的,用它换算成视空间距离(另有 half 重载)。
void TransformScreenUV(inout float2 uv)在 UV 从上开始的平台上按渲染目标翻转像素坐标 y(另有带 screenHeight 的重载)。
void TransformNormalizedScreenUV(inout float2 uv)同上,作用于 0~1 归一化 UV。
float2 GetNormalizedScreenSpaceUV(float4 positionCS)片元里传 SV_POSITION,得到 0~1 屏幕 UV(已处理缩放与翻转)。另有 float2 重载。
uint GetMeshRenderingLayer()取当前渲染器的 Rendering Layer Mask。
float4 ComputeScreenPos(float4 positionCS)已弃用(在 ShaderVariablesFunctions.deprecated.hlsl)。源码注释建议改用 GetVertexPositionInputs().positionNDC。

A.2 SpaceTransforms.hlsl(Core,由 Input.hlsl 引入)

签名说明
float4x4 GetObjectToWorldMatrix()返回 UNITY_MATRIX_M。
float4x4 GetWorldToObjectMatrix()返回 UNITY_MATRIX_I_M。
float4x4 GetPrevObjectToWorldMatrix()上一帧的模型矩阵,运动矢量用。
float4x4 GetWorldToViewMatrix()返回 UNITY_MATRIX_V。
float4x4 GetViewToWorldMatrix()返回 UNITY_MATRIX_I_V。
float4x4 GetWorldToHClipMatrix()返回 UNITY_MATRIX_VP。
float4x4 GetViewToHClipMatrix()返回 UNITY_MATRIX_P。
real GetOddNegativeScale()物体缩放含奇数个负分量时为 -1,否则为 1(取自 unity_WorldTransformParams.w)。
float3 TransformObjectToWorld(float3 positionOS)模型空间位置 → 世界空间。
float3 TransformWorldToObject(float3 positionWS)世界空间位置 → 模型空间。
float3 TransformWorldToView(float3 positionWS)世界 → 视空间。视空间是右手系,相机前方 z 为负。
float3 TransformViewToWorld(float3 positionVS)视空间 → 世界。
float4 TransformObjectToHClip(float3 positionOS)模型空间 → 齐次裁剪空间,替代 Built-in 的 UnityObjectToClipPos。
float4 TransformWorldToHClip(float3 positionWS)世界 → 裁剪空间。
float4 TransformWViewToHClip(float3 positionVS)视空间 → 裁剪空间。注意函数名里多了个 W。
float3 TransformObjectToWorldDir(float3 dirOS, bool doNormalize = true)方向向量(如切线)模型 → 世界,默认归一化。
float3 TransformWorldToObjectDir(float3 dirWS, bool doNormalize = true)方向向量 世界 → 模型。
real3 TransformWorldToViewDir(real3 dirWS, bool doNormalize = false)方向 世界 → 视空间,默认不归一化。
real3 TransformViewToWorldDir(real3 dirVS, bool doNormalize = false)方向 视空间 → 世界。
real3 TransformWorldToViewNormal(real3 normalWS, bool doNormalize = false)法线 世界 → 视空间。
real3 TransformViewToWorldNormal(real3 normalVS, bool doNormalize = false)法线 视空间 → 世界。
real3 TransformWorldToHClipDir(real3 directionWS, bool doNormalize = false)方向 世界 → 裁剪空间。
float3 TransformObjectToWorldNormal(float3 normalOS, bool doNormalize = true)法线 模型 → 世界,用逆转置矩阵,正确处理非均匀缩放。
float3 TransformWorldToObjectNormal(float3 normalWS, bool doNormalize = true)法线 世界 → 模型。
real3x3 CreateTangentToWorld(real3 normal, real3 tangent, real flipSign)用 N、T 和副切线符号构造 TBN 矩阵(行为 T、B、N)。
real3 TransformTangentToWorld(float3 normalTS, real3x3 tangentToWorld, bool doNormalize = false)切线空间法线(法线贴图)→ 世界空间。
real3 TransformWorldToTangent(real3 normalWS, real3x3 tangentToWorld, bool doNormalize = true)世界空间法线 → 切线空间。
real3 TransformWorldToTangentDir(real3 dirWS, real3x3 tangentToWorld, bool doNormalize = false)方向 世界 → 切线空间(视差映射里常用)。
real3 TransformTangentToWorldDir(real3 dirWS, real3x3 tangentToWorld, bool doNormalize = false)方向 切线 → 世界。
real3 TransformTangentToObject(real3 dirTS, real3x3 tangentToWorld)切线空间 → 模型空间。
real3 TransformObjectToTangent(real3 dirOS, real3x3 tangentToWorld)模型空间 → 切线空间。

A.3 Lighting.hlsl(URP)

签名说明
half3 LightingLambert(half3 lightColor, half3 lightDir, half3 normal)Lambert 漫反射:lightColor * saturate(N·L)。
half3 LightingSpecular(half3 lightColor, half3 lightDir, half3 normal, half3 viewDir, half4 specular, half smoothness)Blinn-Phong 高光,smoothness 在这里是指数。
half3 LightingPhysicallyBased(BRDFData brdfData, Light light, half3 normalWS, half3 viewDirectionWS)单盏灯的 PBR 直接光:BRDF × 辐照度(含距离衰减与阴影)。
half3 LightingPhysicallyBased(BRDFData brdfData, half3 lightColor, half3 lightDirectionWS, half lightAttenuation, half3 normalWS, half3 viewDirectionWS)同上,直接传灯光参数。另有带 bool specularHighlightsOff、带清漆层 BRDFData brdfDataClearCoat 的重载。
half3 VertexLighting(float3 positionWS, half3 normalWS)_ADDITIONAL_LIGHTS_VERTEX 时逐顶点累加附加光的 Lambert。
half3 CalculateBlinnPhong(Light light, InputData inputData, SurfaceData surfaceData)SimpleLit 用的单灯 Blinn-Phong(漫反射 + 可选高光)。
LightingData CreateLightingData(InputData inputData, SurfaceData surfaceData)初始化光照分项累加结构(GI、主光、附加光、顶点光、自发光)。
half3 CalculateLightingColor(LightingData lightingData, half3 albedo)把各分项加起来(受调试模式开关影响)。
half4 CalculateFinalColor(LightingData lightingData, half alpha)输出最终颜色;另有带 albedo 与 fogCoord 的重载。
half4 UniversalFragmentPBR(InputData inputData, SurfaceData surfaceData)Lit 的完整片元光照:GI + 主光 + 附加光 + 自发光。写自定义 PBR 时最省事的入口。
half4 UniversalFragmentPBR(InputData inputData, half3 albedo, half metallic, half3 specular, half smoothness, half occlusion, half3 emission, half alpha)同上,用散装参数代替 SurfaceData。
half4 UniversalFragmentBlinnPhong(InputData inputData, SurfaceData surfaceData)SimpleLit 的完整片元光照。
half4 UniversalFragmentBlinnPhong(InputData inputData, half3 diffuse, half4 specularGloss, half smoothness, half3 emission, half alpha, half3 normalTS)同上,散装参数版本。
half4 UniversalFragmentBakedLit(InputData inputData, SurfaceData surfaceData)BakedLit:只有烘焙 GI 乘颜色。另有 (InputData, half3 color, half alpha, half3 normalTS) 重载。

同文件里还有三个宏,用来在 Varyings 里声明 / 填写光照贴图 UV 或逐顶点 SH:DECLARE_LIGHTMAP_OR_SH(lmName, shName, index)、OUTPUT_LIGHTMAP_UV(lightmapUV, lightmapScaleOffset, OUT)、OUTPUT_SH(normalWS, OUT)。开了 LIGHTMAP_ON 时声明成 float2 光照贴图 UV,否则声明成 half3 SH。

A.4 RealtimeLights.hlsl 与 LightCookie.hlsl(URP)

签名说明
Light GetMainLight()主光(方向光):方向、颜色、距离衰减,阴影衰减固定为 1。
Light GetMainLight(float4 shadowCoord)同上,并用阴影坐标算实时阴影。
Light GetMainLight(float4 shadowCoord, float3 positionWS, half4 shadowMask)实时阴影 + Shadowmask 烘焙阴影 + 阴影淡出,开 _LIGHT_COOKIES 时还会乘 Cookie。
Light GetMainLight(InputData inputData, half4 shadowMask, AmbientOcclusionFactor aoFactor)Lit 实际用的版本,额外乘 SSAO 的直接光遮蔽。
int GetAdditionalLightsCount()当前物体受影响的附加光数量。Forward+ 下恒返回 0,必须配合 LIGHT_LOOP_BEGIN 使用。
Light GetAdditionalLight(uint i, float3 positionWS)第 i 盏附加光(点光 / 聚光),含距离与角度衰减,不含阴影。
Light GetAdditionalLight(uint i, float3 positionWS, half4 shadowMask)同上,含实时与烘焙阴影、Cookie。
Light GetAdditionalLight(uint i, InputData inputData, half4 shadowMask, AmbientOcclusionFactor aoFactor)同上,再乘 SSAO 直接光遮蔽。
Light GetAdditionalPerObjectLight(int perObjectLightIndex, float3 positionWS)按灯光缓冲索引直接取灯(不经过逐物体索引映射)。
int GetPerObjectLightIndex(uint index)逐物体灯光列表第 index 项 → 全局灯光索引。
uint GetPerObjectLightIndexOffset()结构化缓冲模式下的逐物体灯光索引偏移。
float DistanceAttenuation(float distanceSqr, half2 distanceAttenuation)URP 的距离衰减:平方反比,在灯光范围边缘平滑归零。
half AngleAttenuation(half3 spotDirection, half3 lightDirection, half2 spotAttenuation)聚光灯内外锥角衰减。
half4 CalculateShadowMask(InputData inputData)按关键字从光照贴图或 unity_ProbesOcclusion 取 Shadowmask。
real3 SampleMainLightCookie(float3 samplePositionWS)采样主光 Cookie(LightCookie/LightCookie.hlsl)。
real3 SampleAdditionalLightCookie(int perObjectLightIndex, float3 samplePositionWS)采样附加光 Cookie(同文件)。
// 兼容 Forward / Forward+ 的附加光循环(片元里必须有名为 inputData 的 InputData 变量)
uint count = GetAdditionalLightsCount();
LIGHT_LOOP_BEGIN(count)
    Light light = GetAdditionalLight(lightIndex, inputData.positionWS, half4(1, 1, 1, 1));
    color += LightingLambert(light.color * light.distanceAttenuation * light.shadowAttenuation,
                             light.direction, inputData.normalWS);
LIGHT_LOOP_END

Forward+ 版的 LIGHT_LOOP_BEGIN 宏内部直接引用 inputData.normalizedScreenSpaceUV 和 inputData.positionWS,所以变量名必须叫 inputData。另外,Forward+ 下方向光不放进聚类结构,附加方向光要用 URP_FP_DIRECTIONAL_LIGHTS_COUNT 单独循环,Lit 的实现见 Lighting.hlsl 里的 UniversalFragmentPBR。

A.5 Shadows.hlsl(URP)

签名说明
float4 TransformWorldToShadowCoord(float3 positionWS)世界坐标 → 主光阴影图坐标;开级联时自动选级联;屏幕空间阴影模式下返回屏幕坐标。
float4 GetShadowCoord(VertexPositionInputs vertexInput)顶点阶段的便捷版,按关键字选阴影图坐标或屏幕坐标。
half ComputeCascadeIndex(float3 positionWS)根据级联包围球判断当前点属于第几级级联。
half MainLightRealtimeShadow(float4 shadowCoord)主光实时阴影衰减(0=全影,1=无影)。没有主光阴影关键字时直接返回 1。
half MainLightShadow(float4 shadowCoord, float3 positionWS, half4 shadowMask, half4 occlusionProbeChannels)实时阴影 + 烘焙阴影 + 距离淡出合成后的主光阴影。
half AdditionalLightRealtimeShadow(int lightIndex, float3 positionWS, half3 lightDirection)附加光实时阴影(支持点光源立方体阴影)。
half AdditionalLightShadow(int lightIndex, float3 positionWS, half3 lightDirection, half4 shadowMask, half4 occlusionProbeChannels)附加光的实时 + 烘焙阴影合成。
float3 ApplyShadowBias(float3 positionWS, float3 normalWS, float3 lightDirection)ShadowCaster Pass 用:沿灯光方向做深度偏移、沿法线内缩做法线偏移(读 _ShadowBias)。
real SampleShadowmap(TEXTURE2D_SHADOW_PARAM(ShadowMap, sampler_ShadowMap), float4 shadowCoord, ShadowSamplingData samplingData, half4 shadowParams, bool isPerspectiveProjection = true)底层阴影图采样,按软阴影关键字选择滤波。
real SampleShadowmapFiltered(TEXTURE2D_SHADOW_PARAM(ShadowMap, sampler_ShadowMap), float4 shadowCoord, ShadowSamplingData samplingData)软阴影 PCF 滤波;另有 LowQuality / MediumQuality / HighQuality 三个具体版本。
half SampleScreenSpaceShadowmap(float4 shadowCoord)屏幕空间阴影纹理采样(_MAIN_LIGHT_SHADOWS_SCREEN)。
ShadowSamplingData GetMainLightShadowSamplingData()主光阴影图的偏移与尺寸参数。
half4 GetMainLightShadowParams()x = 阴影强度,y = 是否软阴影(1/0),z/w 用于阴影距离淡出。
half4 GetAdditionalLightShadowParams(int lightIndex)附加光阴影参数:x = 强度,y ≥ 1 表示软阴影(1/2/3 = 低/中/高质量),z = 是否点光,w = 首个阴影切片索引。
half GetMainLightShadowFade(float3 positionWS)阴影在“最大阴影距离”附近的淡出系数。
half GetAdditionalLightShadowFade(float3 positionWS)附加光阴影淡出系数。
half MixRealtimeAndBakedShadows(half realtimeShadow, half bakedShadow, half shadowFade)在阴影距离内外混合实时与烘焙阴影。
half BakedShadow(half4 shadowMask, half4 occlusionProbeChannels)从 Shadowmask 中取当前灯对应通道的烘焙阴影。

A.6 GlobalIllumination.hlsl(URP)

签名说明
half3 SampleSH(half3 normalWS)逐像素完整计算 L0+L1+L2 球谐环境光,替代 Built-in 的 ShadeSH9。
half3 SampleSHVertex(half3 normalWS)顶点阶段部分:EVALUATE_SH_VERTEX 时算全部,EVALUATE_SH_MIXED 时只算 L2,否则返回 0。
half3 SampleSHPixel(half3 L2Term, half3 normalWS)片元阶段部分,与上面配对;两个关键字都没开时退化为 SampleSH。
half3 SampleLightmap(float2 staticLightmapUV, float2 dynamicLightmapUV, half3 normalWS)采样静态 / 动态光照贴图(含方向性光照贴图)。另有只传 staticLightmapUV 的重载。
half3 GlossyEnvironmentReflection(half3 reflectVector, float3 positionWS, half perceptualRoughness, half occlusion, float2 normalizedScreenSpaceUV)反射探针采样(按粗糙度选 mip、支持盒投影与探针混合)。另有省略屏幕 UV 和省略位置的重载。
half3 GlossyEnvironmentReflection(half3 reflectVector, half perceptualRoughness, half occlusion)最简版:只采样当前反射探针,无盒投影。
half3 BoxProjectedCubemapDirection(half3 reflectionWS, float3 positionWS, float4 cubemapPositionWS, float4 boxMin, float4 boxMax)盒投影修正反射方向。
half3 CalculateIrradianceFromReflectionProbes(half3 reflectVector, float3 positionWS, half perceptualRoughness, float2 normalizedScreenSpaceUV)混合多个反射探针(Forward+ 下从探针图集采样)。
half3 GlobalIllumination(BRDFData brdfData, half3 bakedGI, half occlusion, float3 positionWS, half3 normalWS, half3 viewDirectionWS)间接光合成:漫反射 GI + 镜面反射 + 菲涅耳 + AO。另有不带位置、带清漆层的重载。
void MixRealtimeAndBakedGI(inout Light light, half3 normalWS, inout half3 bakedGI)Subtractive 混合光照模式下从光照贴图中扣除主光贡献。另有带 shadowMask、aoFactor 的重载。
half3 SubtractDirectMainLightFromLightmap(Light mainLight, half3 normalWS, half3 bakedGI)上面函数的核心实现。

宏 SAMPLE_GI 根据关键字展开成 SampleLightmap 或 SampleSHPixel。注意它的参数个数会变:开了 DYNAMICLIGHTMAP_ON 时是 4 个参数 (staticLm, dynamicLm, sh, normalWS),否则是 3 个 (staticLm, sh, normalWS),调用处要用 #if 分开写。

A.7 AmbientOcclusion.hlsl(URP)

签名说明
half SampleAmbientOcclusion(float2 normalizedScreenSpaceUV)采样 SSAO 结果纹理 _ScreenSpaceOcclusionTexture。
AmbientOcclusionFactor GetScreenSpaceAmbientOcclusion(float2 normalizedScreenSpaceUV)返回间接光 AO 与直接光 AO 两个值;未开 _SCREEN_SPACE_OCCLUSION 时均为 1。
AmbientOcclusionFactor CreateAmbientOcclusionFactor(float2 normalizedScreenSpaceUV, half occlusion)先取 SSAO,再让间接光 AO 与材质 AO 取较小值(直接光 AO 只来自 SSAO)。
AmbientOcclusionFactor CreateAmbientOcclusionFactor(InputData inputData, SurfaceData surfaceData)同上,从结构体取参数。

A.8 BRDF.hlsl(URP)

签名说明
inline void InitializeBRDFData(inout SurfaceData surfaceData, out BRDFData brdfData)由表面数据算出 BRDF 常量(diffuse、specular、粗糙度等),金属 / 高光两种工作流都支持。
inline void InitializeBRDFData(half3 albedo, half metallic, half3 specular, half smoothness, inout half alpha, out BRDFData outBRDFData)散装参数版;_ALPHAPREMULTIPLY_ON 时会改写 alpha。
inline void InitializeBRDFDataDirect(half3 albedo, half3 diffuse, half3 specular, half reflectivity, half oneMinusReflectivity, half smoothness, inout half alpha, out BRDFData outBRDFData)直接给定 diffuse / specular 时用。
inline void InitializeBRDFDataClearCoat(half clearCoatMask, half clearCoatSmoothness, inout BRDFData baseBRDFData, out BRDFData outBRDFData)初始化清漆层 BRDF(ComplexLit)。
BRDFData CreateClearCoatBRDFData(SurfaceData surfaceData, inout BRDFData brdfData)同上的便捷封装;未开清漆关键字时返回空数据。
half OneMinusReflectivityMetallic(half metallic)金属工作流下漫反射所占比例:(1 - metallic) * 0.96。
half ReflectivitySpecular(half3 specular)高光工作流下由高光色估算反射率。
half MetallicFromReflectivity(half reflectivity)反射率 → 金属度的反推。
half DirectBRDFSpecular(BRDFData brdfData, half3 normalWS, half3 lightDirectionWS, half3 viewDirectionWS)URP 的直接光镜面项:GGX 分布 × 合并近似的 V·F 项(移动端优化版)。
half3 DirectBRDF(BRDFData brdfData, half3 normalWS, half3 lightDirectionWS, half3 viewDirectionWS)diffuse + specularTerm * specular,受 _SPECULARHIGHLIGHTS_OFF 控制。
half3 DirectBDRF(BRDFData brdfData, half3 normalWS, half3 lightDirectionWS, half3 viewDirectionWS, bool specularHighlightsOff)源码里的拼写就是 BDRF;Deprecated.hlsl 用宏把 DirectBDRF 重定向到 DirectBRDF,两个名字都能用。
half3 EnvironmentBRDF(BRDFData brdfData, half3 indirectDiffuse, half3 indirectSpecular, half fresnelTerm)间接光的 BRDF 合成。
half3 EnvironmentBRDFSpecular(BRDFData brdfData, half fresnelTerm)间接镜面项的“预积分”近似系数。
half3 EnvironmentBRDFClearCoat(BRDFData brdfData, half clearCoatMask, half3 indirectSpecular, half fresnelTerm)清漆层的间接镜面。
half3 ConvertF0ForClearCoat15(half3 f0)把底层 F0 换算成“清漆(IOR 1.5)下方”的等效 F0。
π 的约定URP BRDF.hlsl 的漫反射直接用 albedo × (1 − 反射率),镜面项也按同样的约定省掉了 1/π(相当于把 π 并进了灯光强度)。而 Core BSDF.hlsl 里的 D_GGX、Lambert()、DisneyDiffuse 都带 INV_PI。混用两套函数时要统一约定,否则亮度会差 π 倍。

A.9 SurfaceInput.hlsl(URP)与 LitInput / LitForwardPass(URP/Shaders)

签名说明
half4 SampleAlbedoAlpha(float2 uv, TEXTURE2D_PARAM(albedoAlphaMap, sampler_albedoAlphaMap))采样基础色贴图。
half3 SampleNormal(float2 uv, TEXTURE2D_PARAM(bumpMap, sampler_bumpMap), half scale = half(1.0))采样并解码法线贴图;没有 _NORMALMAP 关键字时直接返回 (0,0,1)。
half3 SampleEmission(float2 uv, half3 emissionColor, TEXTURE2D_PARAM(emissionMap, sampler_emissionMap))采样自发光;没有 _EMISSION 时返回 0。
half Alpha(half albedoAlpha, half4 color, half cutoff)算最终 alpha 并调用 AlphaDiscard。
inline void InitializeStandardLitSurfaceData(float2 uv, out SurfaceData outSurfaceData)Lit 材质的表面数据填充(Shaders/LitInput.hlsl)。
half4 SampleMetallicSpecGloss(float2 uv, half albedoAlpha)Lit 的金属度 / 高光 + 光滑度采样(Shaders/LitInput.hlsl)。
half SampleOcclusion(float2 uv)Lit 的 AO 贴图采样(Shaders/LitInput.hlsl)。
void InitializeInputData(Varyings input, half3 normalTS, out InputData inputData)Lit 的 InputData 填充(Shaders/LitForwardPass.hlsl),自己写 InputData 时可对照它。

A.10 场景深度 / 法线 / 颜色纹理(URP 三个 Declare 文件)

签名说明
float SampleSceneDepth(float2 uv)DeclareDepthTexture.hlsl:采样 _CameraDepthTexture,返回原始设备深度。
float LoadSceneDepth(uint2 uv)同文件:按像素坐标读取,不过滤。
float3 SampleSceneNormals(float2 uv)DeclareNormalsTexture.hlsl:采样 _CameraNormalsTexture,世界空间法线;_GBUFFER_NORMALS_OCT 时自动八面体解码。
float3 LoadSceneNormals(uint2 uv)同文件:按像素读取。
float3 SampleSceneColor(float2 uv)DeclareOpaqueTexture.hlsl:采样 _CameraOpaqueTexture(不透明物体画完后的拷贝)。
float3 LoadSceneColor(uint2 uv)同文件:按像素读取。

A.11 Common.hlsl(Core)

签名说明
float Linear01Depth(float depth, float4 zBufferParam)深度缓冲值 → 0~1 线性深度(相机处为 0、远平面为 1),传 _ZBufferParams。不适用正交相机。
float Linear01DepthFromNear(float depth, float4 zBufferParam)同上,但近平面为 0。
float LinearEyeDepth(float depth, float4 zBufferParam)深度缓冲值 → 视空间距离(米),传 _ZBufferParams。不适用正交相机。
float LinearEyeDepth(float3 positionWS, float4x4 viewMatrix)已有世界坐标时求视深度,任何投影都适用。
float3 ComputeWorldSpacePosition(float2 positionNDC, float deviceDepth, float4x4 invViewProjMatrix)屏幕 UV + 深度 → 世界坐标重建,常配 UNITY_MATRIX_I_VP。
float3 ComputeViewSpacePosition(float2 positionNDC, float deviceDepth, float4x4 invProjMatrix)屏幕 UV + 深度 → 视空间坐标。
float4 ComputeClipSpacePosition(float2 positionNDC, float deviceDepth)NDC + 深度 → 裁剪空间(已处理 y 翻转)。
float2 ComputeNormalizedDeviceCoordinates(float3 position, float4x4 clipSpaceTransform = k_identity4x4)位置投影到 0~1 屏幕坐标。
PositionInputs GetPositionInput(float2 positionSS, float2 invScreenSize)由像素坐标填写 PositionInputs(含 0~1 屏幕 UV)。
float4 GetFullScreenTriangleVertexPosition(uint vertexID, float z = UNITY_NEAR_CLIP_VALUE)用 SV_VertexID 生成全屏三角形顶点,免顶点缓冲。
float2 GetFullScreenTriangleTexCoord(uint vertexID)配套的全屏三角形 UV。
real3 SafeNormalize(float3 inVec)长度为 0 时不产生 NaN 的归一化。
real SafeDiv(real numer, real denom)防除零 / NaN 的除法。
real SafeSqrt(real x)负数输入时返回 0 的平方根。
PositivePow(base, power)模板函数,pow(abs(base), power),消除负底数警告。另有 SafePositivePow。
Sq(x) / Max3(a, b, c) / Min3(a, b, c)模板函数:平方、三者最大 / 最小(对各种 float/half 维度都有版本)。
real Pow4(real x)x⁴。
real Smoothstep01(real x)0~1 区间的 smoothstep(3x² − 2x³)。
real Smootherstep01(real x)更平滑的五次版本。
real3 Orthonormalize(real3 tangent, real3 normal)Gram-Schmidt:让切线与法线正交。
real DegToRad(real deg) / real RadToDeg(real rad)角度与弧度互换。
real FastACos(real inX)反余弦的快速近似;同类还有 FastASin、FastATan、FastAtan2。
float2 DirectionToLatLongCoordinate(float3 unDir)方向 → 经纬度贴图 UV。
float3 LatlongToDirectionCoordinate(float2 coord)经纬度 UV → 方向。
float ComputeTextureLOD(float2 uv, float bias = 0.0)根据屏幕导数估算 mip 级别(另有带 texelSize、导数的重载)。
float CopySign(float x, float s, bool ignoreNegZero = true)取 x 的绝对值、s 的符号。
bool IsNaN(float x)NaN 检测;另有 AnyIsNaN、IsInf、IsFinite。
real4 CompositeOver(real4 front, real4 back)预乘 alpha 的 Over 合成。
void LODDitheringTransition(uint2 fadeMaskSeed, float ditherFactor)按哈希噪声做 LOD 抖动过渡(ditherFactor 取自 unity_LODFade)。
float SharpenAlpha(float alpha, float alphaClipTreshold)为 Alpha To Coverage 锐化 alpha。

A.12 Packing.hlsl(Core,由 Core.hlsl 引入)

签名说明
real3 UnpackNormal(real4 packedNormal)按平台编码(DXT5nm / BC5 / ASTC / RGB)解码法线贴图。
real3 UnpackNormalScale(real4 packedNormal, real bumpScale)同上并缩放 xy 强度,替代 Built-in 的 UnpackScaleNormal。
real3 UnpackNormalRGB(real4 packedNormal, real scale = 1.0)解码普通 RGB 编码法线。
real3 UnpackNormalRGBNoScale(real4 packedNormal)RGB 编码,无缩放。
real3 UnpackNormalAG(real4 packedNormal, real scale = 1.0)解码 AG 两通道法线并重建 z。
real3 UnpackNormalmapRGorAG(real4 packedNormal, real scale = 1.0)同时兼容 RG(BC5)与 AG(DXT5nm)。
float2 PackNormalOctQuadEncode(float3 n)法线 → 八面体编码(G-Buffer 用)。
float3 UnpackNormalOctQuadEncode(float2 f)八面体编码 → 法线。
real2 PackNormalHemiOctEncode(real3 n)半球八面体编码。
float3 PackFloat2To888(float2 f)两个 12bit 值打包进 RGB888。
float2 Unpack888ToFloat2(float3 x)上面的逆运算。
real2 PackFloatToR8G8(real f)把一个 0~1 的 float 拆进两个 8 位通道;逆函数 UnpackFloatFromR8G8。
real4 PackToLogLuv(real3 vRGB)HDR 颜色 → LogLuv 编码。
uint PackToR11G11B10f(float3 rgb)RGB 打包为 R11G11B10 浮点格式。

A.13 Color.hlsl(Core,经 Core.hlsl 间接引入)

签名说明
real3 SRGBToLinear(real3 c)精确的 sRGB → 线性(分段曲线);另有 real、real2、real4 重载。
real3 LinearToSRGB(real3 c)线性 → sRGB。
real3 FastSRGBToLinear(real3 c)近似版 sRGB → 线性,更快。
real3 FastLinearToSRGB(real3 c)近似版线性 → sRGB。
real3 Gamma22ToLinear(real3 c)纯 2.2 次幂曲线;另有 LinearToGamma22、Gamma20ToLinear。
real Luminance(real3 linearRgb)线性 RGB 亮度(Rec.709 权重)。
real AcesLuminance(real3 linearRgb)ACES 色彩空间下的亮度。
real3 RgbToHsv(real3 c)RGB → HSV。
real3 HsvToRgb(real3 c)HSV → RGB。
real RotateHue(real value, real low, real hi)色相旋转并回绕到 [low, hi]。
real3 Desaturate(real3 value, real saturation)按饱和度向亮度灰插值。
real3 RGBToYCoCg(real3 rgb)RGB → YCoCg(TAA、压缩常用);逆函数 YCoCgToRGB。
float3 SoftLight(float3 base, float3 blend)柔光混合模式。
float3 LinearToLogC(float3 x)线性 → LogC(调色 LUT 用);逆函数 LogCToLinear。
real3 NeutralTonemap(real3 x)Neutral 色调映射曲线。
float3 AcesTonemap(float3 aces)ACES 色调映射(输入需先转到 ACES 色彩空间)。
real3 FastTonemap(real3 c)快速可逆色调映射 c / (max(r,g,b) + 1);逆函数 FastTonemapInvert。
real3 ApplyLut2D(TEXTURE2D_PARAM(tex, samplerTex), float3 uvw, float3 scaleOffset)采样条带式 2D LUT。
half4 EncodeRGBM(half3 color)HDR → RGBM 编码;逆函数 DecodeRGBM。

A.14 BSDF.hlsl / CommonMaterial.hlsl / CommonLighting.hlsl(Core)

签名说明
real3 F_Schlick(real3 f0, real u)Schlick 菲涅耳,u 通常为 L·H 或 N·V;另有带 f90、标量 f0 的重载。
real D_GGX(real NdotH, real roughness)GGX 法线分布,含 1/π;D_GGXNoPI 不含。
real V_SmithJointGGX(real NdotL, real NdotV, real roughness)高度相关 Smith 可见性项,已除以 4·N·L·N·V(V = G / (4 N·L N·V))。
real V_SmithJointGGXApprox(real NdotL, real NdotV, real roughness)上式的近似版。
real G_MaskingSmithGGX(real NdotV, real roughness)Smith 单向遮蔽项 G1。
real D_GGXAniso(real TdotH, real BdotH, real NdotH, real roughnessT, real roughnessB)各向异性 GGX 分布。
real Lambert()返回 INV_PI;LambertNoPI() 返回 1。
real DisneyDiffuse(real NdotV, real NdotL, real LdotV, real perceptualRoughness)Burley 2012 的 Disney 漫反射(含 1/π)。
real3 D_KajiyaKay(real3 T, real3 H, real specularExponent)Kajiya-Kay 头发高光(源码注释说明这里用的是 Blinn-Phong 形式)。
real3 ShiftTangent(real3 T, real3 N, real shift)沿法线偏移切线,头发双高光用。
real D_Charlie(real NdotH, real roughness)Charlie 布料分布。
real F_FresnelDielectric(real ior, real u)电介质精确菲涅耳。
real IorToFresnel0(real transmittedIor)折射率 → F0。
real PerceptualSmoothnessToPerceptualRoughness(real perceptualSmoothness)1 − smoothness。
real PerceptualRoughnessToRoughness(real perceptualRoughness)感知粗糙度平方 → 线性粗糙度 α。
real PerceptualRoughnessToMipmapLevel(real perceptualRoughness)粗糙度 → 反射探针 mip(ImageBasedLighting.hlsl)。
real3 BlendNormalRNM(real3 n1, real3 n2)Reoriented Normal Mapping 法线混合(细节法线叠加)。
real3 BlendNormal(real3 n1, real3 n2)简单的 UDN 式法线混合。
real3 ComputeTriplanarWeights(real3 normal)三平面映射的三轴权重。
void GetTriplanarCoordinate(float3 position, out float2 uvXZ, out float2 uvXY, out float2 uvZY)三平面映射的三组 UV。
real LerpWhiteTo(real b, real t)lerp(1, b, t),常用于 AO 强度。
real ComputeWrappedDiffuseLighting(real NdotL, real w)Wrap Lighting:saturate((N·L + w) / ((1 + w)²))。
real GetSpecularOcclusionFromAmbientOcclusion(real NdotV, real ambientOcclusion, real roughness)由 AO 推导镜面遮蔽。
real3 GTAOMultiBounce(real visibility, real3 albedo)GTAO 多次反弹近似,让 AO 不至于过暗。
real3x3 GetLocalFrame(real3 localZ)由一个方向构造正交基。

A.15 EntityLighting / SphericalHarmonics / ParallaxMapping / Random(Core)

签名说明
real3 DecodeHDREnvironment(real4 encodedIrradiance, real4 decodeInstructions)解码 HDR 立方体贴图(传 unity_SpecCube0_HDR),替代 Built-in 的 DecodeHDR。
real3 DecodeLightmap(real4 encodedIlluminance, real4 decodeInstructions)解码光照贴图(RGBM / dLDR / HDR)。
real3 SHEvalLinearL0L1(real3 N, real4 shAr, real4 shAg, real4 shAb)只算球谐 L0+L1 项。
real3 SHEvalLinearL2(real3 N, real4 shBr, real4 shBg, real4 shBb, real4 shC)只算球谐 L2 项。
half3 SampleSH9(half4 SHCoefficients[7], half3 N)用 7 个系数完整求值(SampleSH 内部就调它)。
half3 GetViewDirectionTangentSpace(half4 tangentWS, half3 normalWS, half3 viewDirWS)ParallaxMapping.hlsl:求切线空间视线方向。
half2 ParallaxOffset1Step(half height, half amplitude, half3 viewDirTS)单步视差偏移量。
float2 ParallaxMapping(TEXTURE2D_PARAM(heightMap, sampler_heightMap), half3 viewDirTS, half scale, float2 uv)采样高度图(G 通道)并返回 UV 偏移,Lit 的 _PARALLAXMAP 用的就是它。
float InterleavedGradientNoise(float2 pixCoord, int frameCount)Random.hlsl:交错梯度噪声,抖动采样常用。
float GenerateHashedRandomFloat(uint2 v)Random.hlsl:整数哈希得到 [0,1) 随机数(另有 uint、uint3、uint4 重载)。

A.16 LODCrossFade.hlsl(URP)与 Blit.hlsl(Core)

签名说明
void LODFadeCrossFade(float4 positionCS)LOD 交叉淡化:按 unity_LODFade.x 和抖动纹理 clip。在片元里 #ifdef LOD_FADE_CROSSFADE 时用 SV_POSITION 调用。
Varyings Vert(Attributes input)Blit.hlsl:全屏三角形顶点着色器,输出 positionCS 和 texcoord(已应用 _BlitScaleBias)。
float4 FragBlit(Varyings input, SamplerState s)用给定采样器采样 _BlitTexture(mip 为 _BlitMipLevel)。
float4 FragNearest(Varyings input) : SV_Target点采样拷贝(sampler_PointClamp)。
float4 FragBilinear(Varyings input) : SV_Target双线性拷贝(sampler_LinearClamp)。

写全屏后处理 Shader 时,直接 #include "Packages/com.unity.render-pipelines.core/Runtime/Utilities/Blit.hlsl" 并 #pragma vertex Vert,片元里用 SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, input.texcoord) 读源图。C# 侧配套的是 Blitter.BlitCameraTexture(CommandBuffer cmd, RTHandle source, RTHandle destination, Material material, int pass)。sampler_PointClamp、sampler_LinearClamp、sampler_PointRepeat、sampler_LinearRepeat 来自 Core/GlobalSamplers.hlsl。

B. 常用内置变量与宏

B.1 时间、相机与屏幕

以下变量都在 URP/UnityInput.hlsl 或 URP/Input.hlsl 中声明,由 URP 每帧 / 每相机设置。分量含义摘自源码注释和 ScriptableRenderer.cs 的赋值代码。

变量分量含义
float4 _Time(t/20, t, t·2, t·3),t 为关卡加载以来的秒数。
float4 _SinTime(sin(t/8), sin(t/4), sin(t/2), sin(t))。
float4 _CosTime(cos(t/8), cos(t/4), cos(t/2), cos(t))。
float4 unity_DeltaTime(dt, 1/dt, smoothDt, 1/smoothDt)。
float4 _TimeParameters(t, sin(t), cos(t), 0)。Shader Graph 的 Time 节点用的就是它。
float3 _WorldSpaceCameraPos相机世界坐标(建议通过 GetCameraPositionWS() 访问)。
float4 _ProjectionParamsx = 1 或 −1(投影被翻转时为 −1),y = 近平面,z = 远平面,w = 1/远平面。
float4 _ScreenParamsx = 宽,y = 高,z = 1 + 1/宽,w = 1 + 1/高(相机目标像素尺寸)。
float4 _ScaledScreenParams同上格式,但按 Render Scale 缩放后的实际渲染分辨率。URP 里算屏幕 UV 应优先用它。
float4 _ZBufferParams普通深度:x = 1 − far/near,y = far/near,z = x/far,w = y/far。UNITY_REVERSED_Z 时:x = −1 + far/near,y = 1,z = x/far,w = 1/far。
float4 unity_OrthoParamsx = 正交相机宽度,y = 正交相机高度,z 未用,w = 1(正交)/ 0(透视)。
float4 _ScreenSize(w, h, 1/w, 1/h),Core 风格的屏幕尺寸。
float4 unity_CameraWorldClipPlanes[6]相机视锥 6 个平面(世界空间)。
float2 _GlobalMipBiasx = Mip Bias,y = 2^MipBias(用于上采样时的全局 mip 偏移)。

B.2 矩阵

名字实际指向说明
UNITY_MATRIX_Munity_ObjectToWorld模型 → 世界,属于 UnityPerDraw CBUFFER(SRP Batcher 依赖它的布局)。
UNITY_MATRIX_I_Munity_WorldToObject世界 → 模型。
UNITY_MATRIX_Vunity_MatrixV世界 → 视空间(右手系,前方 z 为负)。
UNITY_MATRIX_I_Vunity_MatrixInvV视空间 → 世界。
UNITY_MATRIX_POptimizeProjectionMatrix(glstate_matrix_projection)投影矩阵(经过 GPU 平台调整)。
UNITY_MATRIX_I_Punity_MatrixInvP逆投影。
UNITY_MATRIX_VPunity_MatrixVP视图投影。
UNITY_MATRIX_I_VPunity_MatrixInvVP逆视图投影,重建世界坐标用;_InvCameraViewProj 也是它的别名。
UNITY_MATRIX_MV / UNITY_MATRIX_MVP运行时 mul 组合为兼容保留,每次使用都会多一次矩阵乘;推荐用 Transform 系列函数。
UNITY_MATRIX_IT_MV运行时组合MV 的逆转置。
UNITY_PREV_MATRIX_Munity_MatrixPreviousM上一帧模型矩阵(运动矢量)。
unity_CameraProjection独立变量相机本身的投影矩阵,不经过 GL.GetGPUProjectionMatrix;画阴影时它仍是主相机的投影。另有 unity_CameraInvProjection。
unity_WorldToCamera / unity_CameraToWorld独立变量相机变换(与 UNITY_MATRIX_V 的手性约定不同,使用前确认)。
_PrevViewProjMatrix / _NonJitteredViewProjMatrix独立变量上一帧 / 当前帧无抖动的 VP,运动矢量用。

B.3 逐物体与光照变量

变量含义
float4 unity_LODFadex = 淡化值(0~1),y = x 量化到 16 级。
real4 unity_WorldTransformParamsw 通常为 1,奇数个负缩放时为 −1。
float4 unity_RenderingLayer只有 x 有效,需 asuint() 还原 32 位 Rendering Layer Mask。
half4 unity_LightDatay = 影响该物体的附加光数量,z = 主光是否未被剔除(1/0)。
float4 unity_ProbesOcclusion光照探针提供的 Shadowmask 遮蔽。
real4 unity_SpecCube0_HDR反射探针 0 的 HDR 解码参数,传给 DecodeHDREnvironment。
float4 unity_SpecCube0_BoxMax / BoxMin / ProbePosition盒投影参数;BoxMax.w = 混合距离,BoxMin.w = 混合权重,ProbePosition.w = 1 表示启用盒投影。
float4 unity_LightmapST光照贴图 UV 的缩放(xy)与偏移(zw)。动态光照贴图对应 unity_DynamicLightmapST。
real4 unity_SHAr / SHAg / SHAb球谐 L0+L1 系数(每个颜色通道一个 float4)。
real4 unity_SHBr / SHBg / SHBb / unity_SHC球谐 L2 系数。
float4 _MainLightPosition方向光时 xyz = 指向光源的方向、w = 0;点光作主光时 xyz = 位置、w = 1。
half4 _MainLightColorrgb = 颜色 × 强度(线性空间);Forward+ 下 a 表示是否为 Subtractive 混合光照。
uint _MainLightLayerMask主光的 Light Layer 掩码。
half4 _AdditionalLightsCountx = 每物体附加光上限。
float4 _AdditionalLightsPosition[] 等附加光数组:Position、Color、Attenuation、SpotDir、OcclusionProbes、LayerMasks。不要直接读,用 GetAdditionalLight。
half4 _AmbientOcclusionParamx = SSAO 是否启用,w = 直接光 AO 强度。
half4 _GlossyEnvironmentColor没有反射探针时的环境反射颜色。
real4 unity_FogColor / float4 unity_FogParams雾颜色与雾参数(线性模式下 z = −1/(end−start),w = end/(end−start))。
real4 unity_AmbientSky / Equator / GroundGradient 环境光的三色。
UNITY_LIGHTMODEL_AMBIENT宏:glstate_lightmodel_ambient * 2,为兼容保留。
贴图附带变量声明 float4 _BaseMap_ST 可拿到材质面板上的 Tiling(xy) / Offset(zw);声明 float4 _BaseMap_TexelSize 可拿到 (1/宽, 1/高, 宽, 高)。前者要放进 UnityPerMaterial CBUFFER 才能兼容 SRP Batcher。

B.4 平台宏与常量

宏含义
UNITY_REVERSED_ZD3D11/12、Metal、Vulkan、主机上为 1:近平面深度 = 1,远平面 = 0。OpenGL / GLES 上未定义。
UNITY_UV_STARTS_AT_TOPD3D、Metal、Vulkan 上为 1:纹理 v=0 在顶部,渲染到 RT 时可能需要翻转 y。
UNITY_NEAR_CLIP_VALUE裁剪空间近平面 z:反转 Z 平台为 1.0,GL 为 −1.0。
UNITY_RAW_FAR_CLIP_VALUE深度缓冲里远平面的原始值:反转 Z 为 0.0,否则 1.0。判断“天空像素”时用。
UNITY_Z_0_FAR_FROM_CLIPSPACE(coord)Core.hlsl 定义:把裁剪空间 z 统一映射到 [0, far],雾计算用。
PI、TWO_PI、HALF_PI、INV_PICore/Macros.hlsl 定义的常量。注意 SRP 里没有 Built-in 的 UNITY_PI。
HALF_MAX、FLT_EPS、REAL_MIN数值极限常量(HALF_MAX = 65504.0)。
UNITY_BRANCH / UNITY_FLATTEN / UNITY_UNROLL / UNITY_LOOP平台无关的 [branch] / [flatten] / [unroll] / [loop] 属性。
kDielectricSpecBRDF.hlsl:half4(0.04, 0.04, 0.04, 0.96),电介质 F0 = 4%。

B.5 纹理、CBUFFER 与实例化宏

宏作用
TEXTURE2D(textureName)声明 2D 纹理(Metal/D3D 下展开为 Texture2D textureName)。
SAMPLER(samplerName)声明采样器 SamplerState。命名 sampler_贴图名 时自动使用该贴图的导入设置。
TEXTURE2D_X(textureName)XR 单通道立体渲染时展开为纹理数组,否则为普通 2D 纹理。屏幕类纹理(相机颜色、深度、Blit 源)用它。
TEXTURE2D_FLOAT(textureName) / TEXTURE2D_HALF指定精度的纹理声明,深度纹理常用 FLOAT。
TEXTURECUBE(textureName) / TEXTURE3D / TEXTURE2D_ARRAY立方体 / 3D / 数组纹理声明。
TEXTURE2D_SHADOW(textureName) + SAMPLER_CMP(samplerName)阴影图与比较采样器。
TEXTURE2D_PARAM(textureName, samplerName) / TEXTURE2D_ARGS(…)把纹理 + 采样器作为函数形参 / 实参传递。
SAMPLE_TEXTURE2D(textureName, samplerName, coord2)标准采样。平台支持时 Core.hlsl 会把它重定义为叠加 _GlobalMipBias 的版本。
SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod)指定 mip 采样,顶点着色器里只能用它。
SAMPLE_TEXTURE2D_BIAS(…, bias) / SAMPLE_TEXTURE2D_GRAD(…, dpdx, dpdy)mip 偏移采样 / 显式导数采样。
SAMPLE_TEXTURE2D_X(textureName, samplerName, coord2)对 TEXTURE2D_X 采样,自动带上当前眼睛的数组下标。
SAMPLE_TEXTURECUBE(…, coord3) / SAMPLE_TEXTURECUBE_LOD(…, coord3, lod)立方体贴图采样。
SAMPLE_TEXTURE2D_SHADOW(textureName, samplerName, coord3)比较采样,coord3.z 为参考深度。
LOAD_TEXTURE2D(textureName, unCoord2) / LOAD_TEXTURE2D_X按整数像素坐标读取,不过滤。
SAMPLE_DEPTH_TEXTURE(textureName, samplerName, coord2)采样并取 .r。
GATHER_TEXTURE2D(textureName, samplerName, coord2)一次取 2×2 像素的同一通道。
CBUFFER_START(name) … CBUFFER_END常量缓冲。材质属性放 CBUFFER_START(UnityPerMaterial),且所有 Pass 内容一致,才能被 SRP Batcher 合批。
TRANSFORM_TEX(tex, name)tex.xy * name_ST.xy + name_ST.zw(Core/Macros.hlsl)。
UNITY_VERTEX_INPUT_INSTANCE_ID放在 Attributes / Varyings 结构体里,声明实例 ID。
UNITY_SETUP_INSTANCE_ID(input)着色器开头调用,之后 UNITY_MATRIX_M 等才会取到当前实例的数据。
UNITY_TRANSFER_INSTANCE_ID(input, output)把实例 ID 从顶点传到片元。
UNITY_INSTANCING_BUFFER_START(buf) / UNITY_INSTANCING_BUFFER_END(arr)声明逐实例属性缓冲。
UNITY_DEFINE_INSTANCED_PROP(type, var)在上面的缓冲里声明一个逐实例属性。
UNITY_ACCESS_INSTANCED_PROP(arr, var)读取逐实例属性。
UNITY_VERTEX_OUTPUT_STEREO / UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output)XR 立体渲染:在 Varyings 里声明 / 在顶点里写入眼睛索引。
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input)片元里恢复眼睛索引,之后才能正确采样 TEXTURE2D_X。
SRP Batcher 与 GPU Instancing两者不会同时作用于同一次绘制:Shader 兼容 SRP Batcher 且管线开启了它时,URP 优先走 SRP Batcher,材质上的 Enable GPU Instancing 不起作用。实际走了哪条路径,以 Frame Debugger 显示为准。

C. LightMode、Pass 与关键字速查

C.1 LightMode 标签

下表依据 URP 14 Runtime/ 中 new ShaderTagId("…") 的实际用法和内置 Shader 的 Pass 标签整理。“谁来画”指哪个 C# Pass 会按这个标签去找你的 Shader Pass。

LightMode谁来画说明
UniversalForwardDrawObjectsPass(不透明、透明)前向渲染的主 Pass。Deferred 模式下只在透明物体阶段使用:不透明物体改走 UniversalGBuffer,只有 UniversalForward 而没有 GBuffer Pass 的不透明 Shader 在 Deferred 下不会被绘制,这类 Shader 应改标 UniversalForwardOnly。
UniversalForwardOnlyDrawObjectsPass;Deferred 下由“Render Opaques Forward Only”绘制“只能前向着色”的材质(Unlit、BakedLit、ComplexLit、自定义光照)。Deferred 模式下也会以前向方式绘制。
SRPDefaultUnlitDrawObjectsPass、RenderObjectsPassPass 不写 LightMode 时的默认值。同一 SubShader 里不要同时有无标签 Pass 和 UniversalForward,会画两遍(描边“第二个 Pass”正是利用这一点)。
UniversalGBufferGBufferPassDeferred 渲染写 G-Buffer。Lit.shader 里此 Pass 要求 target 4.5,并排除 gles3 / glcore。
ShadowCasterMainLightShadowCasterPass、AdditionalLightsShadowCasterPass(通过 ShadowDrawingSettings)渲染阴影图。没有这个 Pass 的物体不投射阴影。
DepthOnlyDepthOnlyPass深度预渲染(生成 _CameraDepthTexture 的一种路径)。没有它,开启深度纹理时物体可能不出现在深度图里。
DepthNormalsDepthNormalOnlyPass同时写深度和世界法线(_CameraNormalsTexture),SSAO、需要法线的 Renderer Feature 依赖它。
DepthNormalsOnlyDepthNormalOnlyPass;Deferred 下只画这个标签Forward-only 材质(Unlit、BakedLit、ComplexLit)用的版本。Deferred 下普通材质的法线来自 G-Buffer,深度法线预渲染只画 DepthNormalsOnly。
MotionVectorsMotionVectorRenderPass逐物体运动矢量。URP 14 的 Lit 没有这个 Pass,找不到时用内置的 ObjectMotionVectors.shader 作为回退材质。
Meta编辑器光照烘焙(不在运行时渲染)为光照贴图烘焙提供反照率和自发光。Lit 的 Meta Pass 用 UniversalVertexMeta / UniversalFragmentMetaLit。
Universal2D2D Renderer 的 Render2DLightingPass2D 渲染器下的主 Pass。3D 的 Lit / SimpleLit 也带一个,以便在 2D 渲染器里显示。
NormalsRendering2D Renderer2D 光照的法线贴图 Pass(Sprite-Lit-Default)。
LightweightForwardDeferred 下的 Forward-only 列表LWRP 时代的旧名,仅为兼容保留。
Always、ForwardBase、PrepassBase、Vertex、VertexLMRGBM、VertexLMRenderingUtils.RenderObjectsWithErrorBuilt-in 管线的旧标签。URP 不会正常渲染它们,在编辑器和 Development Build 中用粉色错误材质画出来提示你。

另有一个容易和 LightMode 混淆的 Pass 标签 UniversalMaterialType:GBufferPass 用它区分 G-Buffer 材质类型,取值为 Lit、SimpleLit、Unlit、ComplexLit,未写或不认识的值按默认处理。它只影响 Deferred 的光照方式,不决定 Pass 是否被绘制。

C.2 URP 内置 Shader 的 Pass 一览

ShaderPass 的 LightMode(按源码顺序)
LitUniversalForward、ShadowCaster、UniversalGBuffer、DepthOnly、DepthNormals、Meta、Universal2D
SimpleLitUniversalForward、ShadowCaster、UniversalGBuffer、DepthOnly、DepthNormals、Meta、Universal2D
ComplexLitUniversalForwardOnly、ShadowCaster、UniversalGBuffer、DepthOnly、DepthNormalsOnly、Meta、Universal2D
BakedLitUniversalForwardOnly、DepthOnly、DepthNormalsOnly(两个)、Meta、Universal2D
Unlit第一个 Pass 无标签(即 SRPDefaultUnlit)、UniversalGBuffer、DepthOnly、DepthNormalsOnly、Meta

C.3 RenderPassEvent 全部枚举值

摘自 Runtime/Passes/ScriptableRenderPass.cs。数值越小越早执行;同一事件里可以用 RenderPassEvent.AfterRenderingOpaques + 1 这种写法微调先后顺序。

枚举值数值时机(源码注释意译)
BeforeRendering0所有 Pass 之前;此时相机矩阵和立体渲染尚未设置,可用来预先画 LUT 等输入纹理。
BeforeRenderingShadows50阴影图之前;相机矩阵尚未设置。
AfterRenderingShadows100阴影图之后;相机矩阵尚未设置。
BeforeRenderingPrePasses150深度预渲染等 PrePass 之前;相机矩阵已设置。
AfterRenderingPrePasses200PrePass 之后。
BeforeRenderingGbuffer210G-Buffer 之前(Deferred)。
AfterRenderingGbuffer220G-Buffer 之后。
BeforeRenderingDeferredLights230延迟光照之前。
AfterRenderingDeferredLights240延迟光照之后。
BeforeRenderingOpaques250不透明物体之前。
AfterRenderingOpaques300不透明物体之后。
BeforeRenderingSkybox350天空盒之前。
AfterRenderingSkybox400天空盒之后(_CameraOpaqueTexture 默认在此拷贝)。
BeforeRenderingTransparents450透明物体之前。
AfterRenderingTransparents500透明物体之后。
BeforeRenderingPostProcessing550后处理之前,自定义后处理最常用的位置。
AfterRenderingPostProcessing600后处理之后,但在最终 Blit、后处理抗锯齿和调色之前。
AfterRendering1000所有效果之后。

配套的 ScriptableRenderPassInput(传给 ConfigureInput,告诉 URP 本 Pass 需要哪些相机纹理):None = 0、Depth = 1、Normal = 2、Color = 4、Motion = 8,可以按位或组合。

C.4 常用 multi_compile / shader_feature 关键字(以 Lit.shader 为准)

shader_feature 的变体只在有材质用到时才打进包,适合由材质面板开关的功能;multi_compile 的变体总是全部编译,适合由管线在运行时开关的功能。_local 后缀表示局部关键字(不占全局关键字名额),_fragment / _vertex 后缀表示只影响该阶段,可以减少变体数。

关键字谁来开关含义
材质关键字(shader_feature_local,由材质 Inspector 根据属性设置)
_NORMALMAP材质使用了法线贴图。
_PARALLAXMAP材质使用了高度图视差。
_RECEIVE_SHADOWS_OFF材质不接收阴影。
_DETAIL_MULX2 / _DETAIL_SCALED材质细节贴图(是否带细节法线缩放)。
_SURFACE_TYPE_TRANSPARENT材质Surface Type = Transparent。
_ALPHATEST_ON材质开启 Alpha Clipping。AlphaClip、AlphaDiscard 都看它。
_ALPHAPREMULTIPLY_ON / _ALPHAMODULATE_ON材质预乘 alpha(Premultiply)/ 乘法混合(Multiply)。
_EMISSION材质开启自发光。
_METALLICSPECGLOSSMAP材质使用了金属度(或高光)贴图。
_SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A材质光滑度取自基础色贴图的 A 通道。
_OCCLUSIONMAP材质使用了 AO 贴图。
_SPECULARHIGHLIGHTS_OFF材质关闭直接光高光。
_ENVIRONMENTREFLECTIONS_OFF材质关闭环境反射。
_SPECULAR_SETUP材质高光工作流(未定义则为金属工作流)。
管线关键字(multi_compile,由 URP 每帧根据 Asset / 灯光 / Renderer 设置)
_MAIN_LIGHT_SHADOWS / _MAIN_LIGHT_SHADOWS_CASCADE / _MAIN_LIGHT_SHADOWS_SCREENURP主光阴影:单级 / 多级联 / 屏幕空间阴影纹理。
_ADDITIONAL_LIGHTS_VERTEX / _ADDITIONAL_LIGHTSURP(Asset 的附加光模式)附加光逐顶点 / 逐像素。
_ADDITIONAL_LIGHT_SHADOWSURP附加光阴影。
_FORWARD_PLUSURP(Renderer 为 Forward+)Forward+ 聚类光照,附加光数量不再受每物体上限约束。
_SHADOWS_SOFT、_SHADOWS_SOFT_LOW / _MEDIUM / _HIGHURP软阴影及其质量档位(14.0.12 已包含分档关键字)。
_REFLECTION_PROBE_BLENDINGURP(Asset)反射探针混合。
_REFLECTION_PROBE_BOX_PROJECTIONURP(Asset)反射探针盒投影。
_SCREEN_SPACE_OCCLUSIONSSAO Renderer Feature采样屏幕空间 AO。
_DBUFFER_MRT1 / _MRT2 / _MRT3Decal Renderer FeatureDBuffer 贴花(1~3 张 RT)。
_LIGHT_COOKIESURP场景中有带 Cookie 的灯。
_LIGHT_LAYERSURP(Asset 开启 Rendering Layers 用于灯光)按 Rendering Layer 过滤灯光。
EVALUATE_SH_MIXED / EVALUATE_SH_VERTEXURP(Asset 的 SH 计算模式)球谐环境光在顶点 / 混合 / 像素阶段计算;都不定义时为逐像素。
_WRITE_RENDERING_LAYERSURP(Decal Layers 等)额外输出 Rendering Layer 纹理,来自 RenderingLayers.hlsl。
_CASTING_PUNCTUAL_LIGHT_SHADOWURP(ShadowCaster Pass)当前在画点光 / 聚光阴影,偏移改用 _LightPosition 计算方向。
_RENDER_PASS_ENABLEDURP(Native RenderPass)启用 Native RenderPass 时的 G-Buffer 路径(Lit 的 GBuffer Pass 声明)。
_GBUFFER_NORMALS_OCTURP(Deferred 精确法线)G-Buffer 法线用八面体编码。
Unity 引擎关键字
LIGHTMAP_ON / DYNAMICLIGHTMAP_ON引擎物体使用静态 / 实时(Enlighten)光照贴图。
DIRLIGHTMAP_COMBINED引擎方向性光照贴图。
LIGHTMAP_SHADOW_MIXING / SHADOWS_SHADOWMASKURP(按混合光照模式)Subtractive 或 Shadowmask 混合光照。
LOD_FADE_CROSSFADE引擎(LOD Group 设置 Cross Fade)LOD 交叉淡化。
FOG_LINEAR / FOG_EXP / FOG_EXP2引擎(Lighting 窗口雾设置)由 #pragma multi_compile_fog 生成。
INSTANCING_ON引擎由 #pragma multi_compile_instancing 生成。
DOTS_INSTANCING_ONEntities Graphics / BRG由 DOTS.hlsl 的 include_with_pragmas 引入。
DEBUG_DISPLAYRendering Debugger调试视图。
自定义 Shader 最常见的“阴影不显示”Pass 里没有声明 _MAIN_LIGHT_SHADOWS 系列关键字时,MainLightRealtimeShadow 直接返回 1,看起来就像“阴影坏了”。同理,没有 _ADDITIONAL_LIGHTS 时不会计算逐像素附加光,没有 _FORWARD_PLUS 时,在 Forward+ 渲染器下附加光会缺失或不正确。

D. Built-in → URP 迁移对照

右列所有 URP 名字都已在 14.0.12 源码中核实存在。左列是 Built-in(UnityCG.cginc / AutoLight.cginc 等)中的写法。

D.1 Shader 结构与 include

Built-inURP 14备注
CGPROGRAM … ENDCGHLSLPROGRAM … ENDHLSLCGPROGRAM 会自动包含 UnityCG 等文件,与 SRP 库冲突。
#include "UnityCG.cginc"#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"变换、输入变量、工具函数。
Lighting.cginc、AutoLight.cginc…/ShaderLibrary/Lighting.hlsl灯光、阴影、GI 全在这里。
UnityPBSLighting.cgincLighting.hlsl 的 UniversalFragmentPBR
Surface Shader(#pragma surface)无对应;手写 HLSL 或用 Shader GraphURP 不支持 Surface Shader。
SubShader 无管线标签Tags { "RenderPipeline"="UniversalPipeline" }让多管线 Shader 能选到正确的 SubShader。
fixed、fixed4half、half4SRP Core 没有定义 fixed 类型。
float4 _MainTex_ST;(散放)放进 CBUFFER_START(UnityPerMaterial)否则不兼容 SRP Batcher。

D.2 变换与常用函数

Built-inURP 14备注
UnityObjectToClipPos(v.vertex)TransformObjectToHClip(positionOS.xyz)参数是 float3。
mul(unity_ObjectToWorld, v.vertex).xyzTransformObjectToWorld(positionOS.xyz)
UnityWorldToClipPos(posWS)TransformWorldToHClip(positionWS)
UnityObjectToViewPos(v.vertex)TransformWorldToView(TransformObjectToWorld(positionOS))或 GetVertexPositionInputs().positionVS。
UnityObjectToWorldNormal(n)TransformObjectToWorldNormal(normalOS)默认已归一化。
UnityObjectToWorldDir(d)TransformObjectToWorldDir(dirOS)
UnityWorldSpaceViewDir(posWS)GetWorldSpaceViewDir(positionWS)未归一化;归一化版本 GetWorldSpaceNormalizeViewDir。
ObjSpaceViewDir(v)GetObjectSpaceNormalizeViewDir(positionOS)URP 版本已归一化。
UnityWorldSpaceLightDir(posWS)、_WorldSpaceLightPos0GetMainLight().direction、_MainLightPosition方向光 w = 0。
ComputeScreenPos(pos)GetVertexPositionInputs(positionOS).positionNDCComputeScreenPos 仍存在但已标记弃用。
ComputeGrabScreenPos(pos)片元里 GetNormalizedScreenSpaceUV(input.positionCS)直接用 SV_POSITION 算屏幕 UV。
COMPUTE_EYEDEPTH(o.z)-TransformWorldToView(positionWS).z视空间前方 z 为负。
LinearEyeDepth(z) / Linear01Depth(z)LinearEyeDepth(z, _ZBufferParams) / Linear01Depth(z, _ZBufferParams)URP 版本多一个参数。
UnpackNormal(tex) / UnpackScaleNormal(tex, s)UnpackNormal(tex) / UnpackNormalScale(tex, s)名字顺序不同。
ShadeSH9(float4(n, 1))SampleSH(normalWS)
DecodeHDR(c, unity_SpecCube0_HDR)DecodeHDREnvironment(c, unity_SpecCube0_HDR)完整的探针反射建议直接用 GlossyEnvironmentReflection。
LinearToGammaSpace(c) / GammaToLinearSpace(c)LinearToSRGB(c) / SRGBToLinear(c)URP 用精确 sRGB 曲线;近似版为 FastLinearToSRGB。
Luminance(c)Luminance(c)Core Color.hlsl,输入应为线性颜色。
UNITY_PIPI
TRANSFORM_TEX(v.uv, _MainTex)TRANSFORM_TEX(input.uv, _BaseMap)宏同名保留(Core/Macros.hlsl)。

D.3 贴图声明与采样

Built-inURP 14备注
sampler2D _MainTex;TEXTURE2D(_BaseMap); SAMPLER(sampler_BaseMap);纹理与采样器分离,可共用采样器。
tex2D(_MainTex, uv)SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, uv)
tex2Dlod(_MainTex, float4(uv, 0, lod))SAMPLE_TEXTURE2D_LOD(_BaseMap, sampler_BaseMap, uv, lod)顶点着色器采样必须用 LOD 版本。
samplerCUBE + texCUBETEXTURECUBE + SAMPLE_TEXTURECUBE
UNITY_DECLARE_DEPTH_TEXTURE(_CameraDepthTexture)#include "…/ShaderLibrary/DeclareDepthTexture.hlsl"需在 URP Asset 勾选 Depth Texture,或由 Pass 调用 ConfigureInput。
SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, uv)SampleSceneDepth(uv)
_CameraDepthNormalsTexture + DecodeDepthNormalDeclareNormalsTexture.hlsl 的 SampleSceneNormals(uv)URP 的法线纹理是世界空间法线,深度另取。
GrabPass { "_GrabTexture" }DeclareOpaqueTexture.hlsl 的 SampleSceneColor(uv)需勾选 Opaque Texture;只包含不透明物体和天空,看不到其他透明物体。

D.4 光照、阴影与雾

Built-inURP 14备注
_LightColor0GetMainLight().color(或 _MainLightColor)
Tags { "LightMode"="ForwardBase" }"LightMode"="UniversalForward"URP 单 Pass 内处理全部灯光。
"LightMode"="ForwardAdd"(每盏附加光一个 Pass)同一 Pass 内循环 GetAdditionalLight用 LIGHT_LOOP_BEGIN / END 兼容 Forward+。
unity_4LightPosX0 等顶点光VertexLighting(positionWS, normalWS)需 _ADDITIONAL_LIGHTS_VERTEX。
SHADOW_COORDS(n) / TRANSFER_SHADOW(o)Varyings 里放 float4 shadowCoord,顶点里 GetShadowCoord(vertexInput)也可以在片元里调用 TransformWorldToShadowCoord(positionWS)。
SHADOW_ATTENUATION(i) / UNITY_LIGHT_ATTENUATIONGetMainLight(shadowCoord).shadowAttenuation 或 MainLightRealtimeShadow(shadowCoord)需声明主光阴影关键字。
"LightMode"="ShadowCaster" + V2F_SHADOW_CASTER / TRANSFER_SHADOW_CASTER_NORMALOFFSET同名 LightMode;顶点里 ApplyShadowBias(positionWS, normalWS, _LightDirection) 后 TransformWorldToHClip参照 URP 的 Shaders/ShadowCasterPass.hlsl;_LightDirection、_LightPosition 在该文件中声明。
UNITY_FOG_COORDS(n)Varyings 里放 half fogFactor
UNITY_TRANSFER_FOG(o, o.vertex)output.fogFactor = ComputeFogFactor(positionCS.z)
UNITY_APPLY_FOG(i.fogCoord, col)col.rgb = MixFog(col.rgb, fogFactor)Additive 物体用 MixFogColor(…, 0, …) 混合到黑色。
#pragma multi_compile_fwdbase / _fwdadd_fullshadows手动列出 C.4 中的管线关键字以 Lit.shader 为模板抄写。
"LightMode"="Deferred""LightMode"="UniversalGBuffer"G-Buffer 布局不同,不能直接搬。
"LightMode"="Meta""LightMode"="Meta"URP 侧用 UniversalMetaPass.hlsl 的 UniversalVertexMeta / UniversalFragmentMeta。

D.5 C# 与渲染流程

Built-inURP 14备注
OnRenderImage(src, dst) + Graphics.BlitScriptableRendererFeature + ScriptableRenderPass,在 Execute 里用 Blitter.BlitCameraTextureURP 不会调用 OnRenderImage。
后处理栈 v2(Post Processing Stack v2)Volume 框架(VolumeComponent)+ URP 内置后处理URP 不支持 PPv2。
Camera.AddCommandBuffer(CameraEvent…)renderer.EnqueuePass(pass) + RenderPassEvent在 Feature 的 AddRenderPasses 里入队。
Camera.depthTextureMode = DepthTextureMode.DepthURP Asset 勾选 Depth Texture,或 ConfigureInput(ScriptableRenderPassInput.Depth)法线:ScriptableRenderPassInput.Normal。
BuiltinRenderTextureType.CameraTargetrenderer.cameraColorTargetHandle(RTHandle)在管线执行范围外访问会报错,通常在 SetupRenderPasses 或 Pass 内使用。
RenderTexture.GetTemporaryRenderingUtils.ReAllocateIfNeeded + RTHandle14 中旧的 RenderTargetIdentifier 重载已标记 Obsolete。
Projector 组件URP Decal Renderer Feature + Decal Projector
多个 Camera 叠加(Depth Clear Flags)Camera Stack(Base + Overlay)

E. 中英术语表

按类别排列。括号里是本书首次出现时使用的英文写法,和 Unity 编辑器、URP 源码的叫法保持一致。

E.1 管线与架构

中文English解释
可编程渲染管线Scriptable Render Pipeline (SRP)用 C# 控制渲染流程的框架,URP / HDRP 都基于它。
通用渲染管线Universal Render Pipeline (URP)面向全平台的 SRP 实现,本书主角。
内置渲染管线Built-in Render PipelineUnity 传统的固定管线。
渲染器Renderer (Universal Renderer / 2D Renderer)决定一个相机执行哪些 Pass 的配置资产。
渲染器特性Renderer Feature插入到 Renderer 中的自定义扩展。
渲染通道Render Pass一次完整的绘制步骤,如阴影、不透明物体。
前向渲染Forward Rendering逐物体直接计算光照。
前向+ 渲染Forward+把灯光按屏幕分块和深度切片分配,突破每物体灯光上限。
延迟渲染Deferred Rendering先写 G-Buffer,再统一算光照。
几何缓冲G-Buffer延迟渲染中存储表面属性的多张 RT。
渲染目标Render Target (RT)GPU 绘制的目标纹理。
RT 句柄RTHandleSRP 管理 RT 的封装,支持动态分辨率。
命令缓冲CommandBuffer录制 GPU 命令的列表。
相机堆叠Camera StackBase 相机叠加 Overlay 相机。
帧调试器Frame Debugger逐个 Draw Call 查看渲染过程的工具。

E.2 Shader 与 GPU

中文English解释
顶点着色器Vertex Shader逐顶点执行,输出裁剪空间位置。
片元着色器Fragment (Pixel) Shader逐片元执行,输出颜色。
光栅化Rasterization把三角形转成片元的固定功能阶段。
插值器Interpolator / Varyings顶点到片元传递并插值的数据。
裁剪空间Clip Space (HClip)投影后、透视除法前的齐次坐标空间。
标准化设备坐标Normalized Device Coordinates (NDC)透视除法后的坐标。
切线空间Tangent Space由 T、B、N 构成的表面局部坐标系。
着色器变体Shader Variant不同关键字组合编译出的独立程序。
关键字Keyword控制变体的编译开关。
常量缓冲Constant Buffer (CBUFFER)着色器常量的分组存储。
SRP 合批器SRP Batcher缓存材质常量、减少 SetPass 开销的合批机制。
GPU 实例化GPU Instancing一次调用绘制多个相同网格。
绘制调用Draw CallCPU 向 GPU 发出的一次绘制命令。
深度测试Depth Test (ZTest)与深度缓冲比较决定片元是否可见。
深度写入Depth Write (ZWrite)是否把片元深度写入深度缓冲。
反转深度Reversed-Z近处深度为 1、远处为 0,提高精度。
模板测试Stencil Test按模板缓冲的值决定是否绘制。
混合Blending片元颜色与帧缓冲颜色的组合方式。
预乘 AlphaPremultiplied Alpha颜色已乘过 alpha 的表示法。
透明度测试Alpha Test / Alpha Clippingalpha 低于阈值的片元被丢弃。
全屏三角形Fullscreen Triangle用一个大三角形覆盖屏幕做后处理。
多级渐远纹理Mipmap逐级减半的预过滤纹理链。

E.3 光照与 PBR

中文English解释
基于物理的渲染Physically Based Rendering (PBR)依据能量守恒和微表面理论的着色方法。
双向反射分布函数BRDF描述入射光如何被反射到各个方向。
微表面理论Microfacet Theory把表面看作大量微小镜面的统计模型。
法线分布函数Normal Distribution Function (D)微表面法线的统计分布,如 GGX。
几何遮蔽项Geometry / Visibility Term (G / V)微表面之间相互遮挡的比例。
菲涅耳Fresnel (F)反射率随观察角度变化的现象。
基础反射率F0 (Specular Reflectance at Normal Incidence)垂直入射时的反射率,电介质约 4%。
能量守恒Energy Conservation出射能量不超过入射能量。
金属度Metallic金属工作流中区分金属与电介质的参数。
光滑度 / 粗糙度Smoothness / Roughness表面微观起伏的程度,互为反向。
感知粗糙度Perceptual Roughness面向美术、视觉上更线性的粗糙度。
反照率Albedo / Base Color表面固有颜色。
漫反射Diffuse向各方向均匀散射的反射。
镜面反射 / 高光Specular集中在反射方向附近的反射。
半程向量Half Vector (H)光线方向与视线方向的角平分线。
各向异性Anisotropy高光沿某一方向拉伸。
清漆层Clear Coat表面额外的一层透明涂层反射。
次表面散射Subsurface Scattering (SSS)光进入物体内部散射后射出。
全局光照Global Illumination (GI)包含间接光的光照。
球谐函数Spherical Harmonics (SH)用少量系数表示低频环境光。
光照贴图Lightmap烘焙到纹理中的静态光照。
光照探针Light Probe空间采样点上的 SH 光照,用于动态物体。
反射探针Reflection Probe捕获周围环境的立方体贴图。
盒投影Box Projection修正反射探针视差的方法。
基于图像的光照Image-Based Lighting (IBL)用环境贴图计算光照。
环境光遮蔽Ambient Occlusion (AO)表面被周围几何遮挡的程度。
屏幕空间环境光遮蔽Screen Space Ambient Occlusion (SSAO)用深度 / 法线在屏幕空间估算 AO。
光照 CookieLight Cookie投射在灯光上的遮罩图案。
距离衰减Distance Attenuation光强随距离减弱。
线性空间Linear Color Space光照计算应在其中进行的颜色空间。
伽马校正Gamma Correction线性值与显示编码之间的转换。

E.4 阴影

中文English解释
阴影贴图Shadow Map从灯光视角渲染的深度图。
级联阴影Cascaded Shadow Maps (CSM)按距离把视锥分段、各用一张阴影图。
阴影偏移Shadow Bias (Depth / Normal Bias)消除阴影痤疮的偏移量。
阴影痤疮Shadow Acne自阴影产生的条纹噪点。
彼得潘现象Peter Panning偏移过大导致阴影与物体分离。
百分比渐近过滤Percentage-Closer Filtering (PCF)多次比较采样得到软阴影边缘。
软阴影Soft Shadows边缘带半影的阴影。
阴影遮罩Shadowmask把静态物体阴影烘焙进贴图的混合光照模式。
屏幕空间阴影Screen Space Shadows先把主光阴影解析到屏幕纹理再采样。

E.5 后处理与性能

中文English解释
后处理Post-processing对整帧图像做的处理。
体积框架Volume FrameworkURP 按区域混合后处理参数的系统。
泛光Bloom高亮区域向外溢出的光晕。
色调映射Tonemapping把 HDR 亮度压缩到显示范围。
高动态范围High Dynamic Range (HDR)超过 0~1 的颜色范围。
颜色查找表Look-Up Table (LUT)预先计算的颜色映射表。
景深Depth of Field (DoF)焦外模糊。
运动模糊Motion Blur运动方向上的模糊。
运动矢量Motion Vectors每像素在屏幕上的位移。
暗角Vignette画面边缘变暗。
抗锯齿Anti-aliasing (MSAA / FXAA / SMAA / TAA)减少几何边缘锯齿的方法。
渲染缩放Render Scale以低于屏幕的分辨率渲染再放大。
过度绘制Overdraw同一像素被多次着色。
填充率Fill RateGPU 每秒能写出的像素量。
带宽Bandwidth显存读写的数据量,移动端功耗关键。
分块渲染Tile-Based Rendering (TBR / TBDR)移动 GPU 按小块在片上缓存中渲染的架构。
变体剥离Shader Variant Stripping构建时剔除用不到的变体。
细节层次Level of Detail (LOD)按距离切换不同精度的模型。

F. 推荐的进一步学习资料

只列公认的经典,不附具体网址(版本和链接会变,按书名或标题检索即可)。

资料为什么值得读
URP 与 SRP Core 源码(工程的 Library/PackageCache)最权威的“文档”。本附录所有签名都来自这里。遇到行为疑问时,先 grep 函数名,读实现和注释,比任何二手资料都准。
Unity 官方手册与 URP 包文档编辑器设置、Renderer Feature、Volume、Shader 编写约定的官方说明。注意选对 URP 版本(本书为 14.x)。
《Real-Time Rendering》(Akenine-Möller 等著)实时渲染的百科全书,从管线、着色、阴影到后处理都有系统论述,书末参考文献是继续深挖的地图。
Physically Based Rendering: From Theory to Implementation(Pharr、Jakob、Humphreys,即“PBR Book”)离线渲染的经典,讲透辐射度量学、BSDF、蒙特卡洛积分。想真正理解 PBR 公式从何而来,这本书最扎实。
Physically-Based Shading at Disney(Brent Burley,SIGGRAPH 2012 课程笔记)Disney 原理化 BRDF 的出处,解释了 baseColor、metallic、roughness 这套参数为什么好用,Core 的 DisneyDiffuse 就来自它。
Real Shading in Unreal Engine 4(Brian Karis,SIGGRAPH 2013 课程笔记)把 Disney 模型落地到实时引擎的经典:GGX、Schlick 近似、Split-Sum 预积分环境光,是理解游戏引擎 PBR 的必读材料。
SIGGRAPH “Physically Based Shading in Theory and Practice” 系列课程每年的课程笔记汇集了业界 PBR 的最新实践,可配合上面两篇一起读。
LearnOpenGL(Joey de Vries)PBR 章节从零实现 Cook-Torrance 与 IBL 的入门教程,代码直白,适合在读理论之前先跑通一遍。
GPU Gems 系列(NVIDIA)大量经典技巧的原始出处:阴影、水面、次表面散射、后处理等,很多今天仍在使用的思路都能在这里找到源头。
GPU Pro / GPU Zen 系列GPU Gems 的后继,收录更新的游戏渲染实践,适合查特定效果的工程实现。
Understanding the Masking-Shadowing Function in Microfacet-Based BRDFs(Eric Heitz,2014)Smith 遮蔽函数的权威推导,Core BSDF.hlsl 的注释直接引用了它。