US3S4L4——延迟渲染路径
US3S4L4——延迟渲染路径
延迟渲染路径
延迟渲染路径对光照的数量没有任何限制,并且所有灯光都可以采用逐像素渲染。
理论上来说,即使场景中有成百上千个实时灯光,依然可以保持比较流畅的渲染帧率。
它支持法线纹理、阴影等等效果的处理;但是它不能处理半透明物体,并且不支持真正的抗锯齿。 这些不支持的内容会自动使用前向渲染路径。
-
延迟渲染路径处理光照的方式
对光照的数量没有任何限制,并且所有灯光都可以采用逐像素渲染,它不能处理半透明物体,并且不支持真正的抗锯齿
-
延迟渲染路径在哪里进行光照计算
- 第一个Pass:主要判断哪些片元可见,并且将可见片元的相关信息存储到G缓冲区中(对于每个物体,该Pass只会执行一次,通常无需我们自己实现)
- 第二个Pass:利用G缓冲区中各个片元的相关信息进行真正的相关计算,最终将颜色写入颜色缓冲区
-
延迟渲染路径的内置光照变量
Unity会自动填充自定义变量
sampler2D _CameraGBufferTexture0~4
,其中存储的就是G缓冲区中的数据,我们可以通过他们获取数据来进行逻辑处理
延迟渲染路径处理光照的方式
延迟渲染的效率不依赖于场景的复杂度,而是和我们使用的屏幕空间的大小有关。
这是因为延迟渲染路径中除了使用颜色缓冲和深度缓冲外,还会利用一个叫做 G 缓存的额外缓存区,
它会存储我们关心的表面(通常是离摄像机最近的表面)的其他信息,比如表面的法线、位置、材质属性等等。
总之我们需要的信息都存储到缓冲区中,而这些缓冲区可以理解为一张张的2D图片,我们实际上是在这些图像空间中进行处理的。
延迟渲染路径在哪里进行光照计算
延迟渲染路径进行光照计算,还是在 Shader 当中的 Pass
渲染通道中进行计算。延迟渲染路径中主要包含两个 Pass
-
第一个
Pass
(对于每个物体,该Pass
只会执行一次,通常无需我们自己实现)主要判断哪些片元可见,并且将可见片元的相关信息存储到 G 缓冲区中,比如:表面法线、视角方向、漫反射系数等等数据
-
第二个
Pass
:利用 G 缓冲区中各个片元的相关信息进行真正的相关计算,最终将颜色写入颜色缓冲区1
2
3
4Pass
{
Tags { "LightMode" = "Deferred" }
}
注意:在第二个
Pass
中计算光照时,默认情况下只能用 Unity 内置的标准(Standard)光照模型计算
延迟渲染路径的内置光照变量
常用内置光照变量
变量名 | 类型 | 描述 |
---|---|---|
sampler2D _CameraGBufferTexture0 ;sampler2D _CameraGBufferTexture1 ;sampler2D _CameraGBufferTexture2 ;sampler2D _CameraGBufferTexture3 ;…… |
sampler2D |
这些变量是自定义变量,我们一般无需实现延迟渲染路径中的第一个 Pass ,G 缓冲中的相关数据 Unity 会帮助我们存储到这些自定义变量中,我们可以直接使用他们来参与计算:_CameraGBufferTexture0 :漫反射颜色 (RGB),遮挡 (A)。_CameraGBufferTexture1 :镜面反射颜色 (RGB),粗糙度 (A)_CameraGBufferTexture2 :世界空间法线 (RGB),未使用 (A)。_CameraGBufferTexture3 :发射 + 光照 + 光照贴图 + 反射探针缓冲区_CameraGBufferTexture4 :光照遮挡值 (RGBA)…… |
_LightColor | float4 |
光源颜色(#include "UnityDeferredLibrary.cginc" ) |
_LightMatrix0 |
float4x4 |
世界空间到光源空间的变换矩阵(#include "UnityDeferredLibrary.cginc" ) |
为了更好的使用上述的自定义变量,需要先引用 UnityGBuffer.cginc
1 |
假设我们声明了三个自定义的 G 缓冲贴图变量
1 | sampler2D _CameraGBufferTexture0; |
在第一个 Pass
后(无需自己声明),这些 G 缓冲贴图变量就会自动被 Unity 存储 G 缓冲相关数据,
我们便可以在第二个 Pass
内对这些数据进行采样,然后将采样数据传入到 UnityStandardDataFromGbuffer
,
最终就会得到 UnityStandardData
,通过这些数据即可进行光照计算
1 | half4 gbuffer0 = tex2D(_CameraGBufferTexture0, uv); |