[toc]

# Gbuffer 流程

先看一下 URP 在 Deffered 渲染时的 FrameDebug 可以发现,每个过程 (如法线 Pass / 深度 Pass/GBufferPass) 都是单独的 Pass, 不过走的是 SrpBatcher
当上述所有 Pass 走完以后,会进入到 DefferedPass 进行最终的渲染

  1. DepthNormal
  2. DepthOnly
  3. RenderGBuffer
  4. DefferedPass

首先,由于 URP 本身通过将渲染分为了不同渲染时机和 RenderFeature, 所以可以很方便把渲染的逻辑拆出来
比如 URP 的 Lit.shader 用 RenderFeature 来划分 GBuffer 还是 Forward 还是 ShadowCaster 还是 DepthOnly

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Pass
{
Name "ForwardLit"
Tags
{
"LightMode" = "UniversalForward"
}
}

Pass
{
Name "GBuffer"
Tags{
"LightMode" = "UniversalGBuffer"
}
}

其中顶点 / 片元着色器都被包裹在了 LitGBufferPass.hlsl 脚本中

  1. LitGBufferPassFragment->InitializeStandardLitSurfaceData (input.uv,surfaceData) 是存储表面数据,保存在了 surfaceData 中

其中 SurfaceData 结构如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// Must match Universal ShaderGraph master node
struct SurfaceData
{
half3 albedo;
half3 specular;
half metallic;
half smoothness;
half3 normalTS;
half3 emission;
half occlusion;
half alpha;
half clearCoatMask;
half clearCoatSmoothness;
};

然后这里 Break 一下,先回到最初的起点,在 FrameDebug 中我们能够明显的看出 Pass 的执行存在顺序关系 (而且这些顺序也不能随便变更,即 DeferedRendering 必须在其他几何 Pass 之后)

那么 URP 本身是在哪里控制这些 Pass 的执行顺序呢?
在 UniversalRenderer 脚本下的 Setup 函数中我们可以看到如下的几段

  1. Setup 入口处声明了 commandBuffer

  1. 在渲染 UI 前调用 DeferredPass

首先,EnqueueDeferredPass 是在上述所有 NormalsPass 结束后加入 commandBuffer 的,在这个函数中,主要加入了其他几个 Pass

  • GBuffer
  • CopyDepth
  • Deffered
  • ForwardOpaque

所有的 Pass 会被保存到 m_ActiveRenderPassQueue 中

最后,会经由 UniversalRenderer 的父类 ScriptableRenderer 的 Execute 方法将所有对应的 Pass 提交到 CommandBuffer 中
其中 activeRenderPassQueue 等价于 m_ActiveRenderPassQueue 至此,URP 的 Deferred 的渲染从 Shader 到设置到提交的流程就完成了

編集日

*~( ̄▽ ̄)~[お茶]を一杯ください

Solvarg WeChat 支払う

WeChat 支払う

Solvarg Alipay

Alipay

Solvarg PayPal

PayPal