目录
1.什么是延迟渲染
正向渲染(Forward Rendering)的渲染思路是,需要把要渲染的Mesh对场景中每一个(受影响的)光照都要渲染一次。如果一个场景中有N个光源和M个Meshes,那么一次绘制就需要N*M次draw calls。如果场景中Mesh数量很少的话并不会称为性能瓶颈,但是如果Mesh很多并且有多个光源的话,那么它就会称为性能瓶颈。
延迟渲染(Deferred Rendering)就是为了解决场景中存在大量光源的情况而提出的解决方案。前向渲染的光栅化阶段先进行着色,然后进行深度测试。在传统的GPU渲染过程中,一个像素往往经历多个片段着色器的计算,如果前一个计算结果被下一个计算结果覆盖掉(深度测试),那么之前的计算就白白浪费掉了。延迟渲染的思路就是先把所有物体绘制到一个屏幕空间的缓冲中,再逐光源进行着色计算。这样省略了深度测试之前的大量光照计算。前向渲染(Forward Rendering)对于下图这种场景来说渲染出来的结果简直就是幻灯片。
2.延迟渲染的原理
首先我们引入一个重要的概念"Geometry Buffer",或者"GBuffer"。GBuffer是几何缓冲区,用来收集存储单个屏幕像素信息:深度值(z-buffer),法线(normal),纹理坐标(uv)以及材质参数等。这些信息是通过像素着色器存储到Multiple RenderTargets,可以认为就是GBuffers。GBuffers的大小都是相同的,一般设置为屏幕像素大小的TextureBuffer。
延迟渲染一般分两个步骤:
- 把场景的几何信息存储到GBuffers中,一般是通过片段着色器把相应的信息例如:深度值(z-buffer),法线(normal),纹理坐标(uv)以及材质参数等存储到GBuffer中。这个阶段不处理任何光照。
- 对于每个光照,找到照射到的像素点,并从GBuffers中读取到这个像素对应的其他信息,然后和ForwardShading步骤差不多,区别就是数据信息是从GBuffers中得到的,并且多了一步合并结果的步骤。
一个简单的GBuffer存储结果
2.延迟渲染的优点
延迟渲染的一个重要优点就是几何阶段只计算一次,然后一次数据收集,像素阶段只计算一次,不管有多少个光照,都只有一个片段着色器的计算过程。数据收集和读取都非常的高效,并且省去了大量的计算。延迟渲染中物体和光照数量不再互相影响,不管场景中有多少物体,真正和光照进行计算的只是RenderTarget的像素,复杂度仅仅是o(N+M)。
2.延迟渲染的缺点
GBuffers对显存和填充效率要求比较高。对透明度和抗锯齿的处理有点麻烦。