聊聊引擎底层如何实现Deferred延迟渲染

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/jxw167/article/details/85016697

Deferred又称为延迟渲染,它是后处理渲染技术的一种,网上也有相关的定义说明,它主要是采用GBuffer实现的,GBuffer可以存储的信息相比ZBuffer更多,GBuffer存储了法线,位置,灯光信息等等。Unity引擎也提供了Deferred渲染,只是因为在手机端比较耗,所以大部分开发者并不是特别关注,其实它在引擎渲染里面也是非常重要的技术。我们自己编写引擎模块还是要亲自写一下,这样有助于自己更深入的理解,遇到不明白的地方,网上提供了大量的资源供我们参考,其实你能够用别人的技术做出自己的产品,这本身也说明了自己的编程能力,你使用别人的技术首先要先搞清楚原理,这样你才可以用在自己的产品中,否则就不要死板硬套了,会出问题的。
我们在上篇博客中给读者介绍了关于引擎底层对Shader的处理,我们介绍关于Deferred延迟渲染的实现,Shader渲染是需要灯光的支持,延迟渲染同样也有很多种类,如下图所示:

在这里插入图片描述Deferred渲染技术实现首先要初始化G缓冲区,因为我们要渲染的信息都保存在GBuffer中,Deferred渲染核心就是对G缓冲区里面的数据进行处理,上面我们提到过GBuffer缓冲区会保存,位置,法线,光照等信息,引擎也会对它们进行处理。下面是我们对GBuffer缓冲区处理的代码如下所示:
在这里插入图片描述
在上述代码中,我们使用了AddRenderTarget函数用于对GBuffer缓存区中所存信息处理,再把这个函数的实现给读者展示如下所示:
在这里插入图片描述
在此,我们调用了CreateRenderTargetView函数,它是DX的一个重要函数,它主要是用于创建渲染目标视图,读者可自行查阅DX的帮助文档。
GBuffer缓冲区完成后,下面我们将设置渲染状态,将我们GBuffer缓冲区中的信息绑定到渲染目标视图,代码如下所示:
在这里插入图片描述
这样我们的GBuffer才会应用到场景中,当然,我们封装的都是接口,需要在场景去调用我们的接口就可以实现GBuffer的渲染,下面给读者展示的是如何在场景中调用的:
在这里插入图片描述
在引擎中的实现基本完成,后面在场景中再加上灯光就可以了。在实现过程中参考了这篇PPT,推荐给读者供参考:
http://download.nvidia.com/developer/presentations/2004/6800_Leagues/6800_Leagues_Deferred_Shading.pdf
下面给读者展示如何获取GBuffer Shader代码,我们先开看一下结构体的定义如下所示:
在这里插入图片描述
结构体定义了GBuffer存储的信息,我们会在Shader的入口函数中使用,代码如下所示:
在这里插入图片描述
读者可能看到我们的入口函数定义PSMain,为什么不是main或者其他的,这个是我们引擎自定义的接口函数,这样引擎才会执行函数里面的内容,还有我们的Shader中经常需要调用其他Shader中的内容,使用include包含,这些都需要在引擎中事先定义,代码如下所示:
在这里插入图片描述
我们的Shader入口函数我们在前面的函数中其实已经调用过了,为了加深印象,在此给读者再重点标注一下:
在这里插入图片描述
最终我们的Deferred渲染效果图如下所示:
在这里插入图片描述

总结:
实现引擎渲染技术模块,首先要明白其原理,然后再动手编码实现,在实现的过程中我们可以查阅网上的资料,国外的一些PPT或者论坛以及技术博客都有非常详细的讲解,这些都可以帮助我们快速的实现。引擎的封装离不开DX或者OpenGL提供的API图形接口,熟练使用它们也是非常重要的。每天搞清楚一个知识点或者技术点就是一大进步,日积月累你也可以成为专家级别的程序员。

猜你喜欢

转载自blog.csdn.net/jxw167/article/details/85016697