【资料图】
(用于实习,不是为了给大伙讲懂,所以没有展现完整的脚本和实现思路!抱歉)
自定义后处理的终极目标就是适配于内置的volume组件中。因为volume功能完善,还有局部后处理的效果,非常强大。在volume组件中添加自定义的后处理,首先就是需要继承VolumeComponent类,才能够在volume下拉菜单中添加自己想要实现的后处理效果。
光是继承VolumeComponent是远远不够的,我们后处理的核心逻辑还没有实现。在内置管线中我们可以通过void OnRenderImage()函数实现后处理。而对于非built-in管线,unity提供了RenderFeature脚本,一个更加灵活,可操作性更高,为SRP而生的后处理框架。因为只提供了这一种方法,我们绕不开这座大山。RenderFeature里有两个类,创建两个脚本分别管理这两个类。
第一个类里有两个函数。首先我们需要自己声明第二个类的字段(把第二个类当做成一个RenderPass)。Create()里初始化我们声明的字段,需要为RenderPass设置RenderPassEvent,也可以设置一些自定义的属性。 AddRenderPasses()主要调用renderer.EnqueuePass()将我们声明的字段(RenderPass)添加到渲染序列当中去。
第二个类里,OnCameraSetup()用于配置一些渲染数据,为命令缓冲提前创建temporaryRT。OnCameraCleanup()是在该RenderPass调用完成后,清除所有分配的资源。 配置好所需要的渲染环境,最终在Execute()实现我们的后处理逻辑。主要实现流程是:通过CommandBufferPool.Get()调用一个CommandBuffer(cb),给cb设置渲染目标(也就是当前摄像机的RenderTexture)。然后调用volumeComp.Render(cb, renderingData.cameraData, source, renderTarget)。volumeComp是我们自定义的后处理脚本!通过下图获得。
现在来介绍此方法相比于常规在renderfeature中写后处理的优势。主要体现在 在Execute()函数里,我们并不是只实现一个后处理效果,而是先获取我们所有激活的后处理,添加到自己声明的List<PostProcessVolumeComponent>。
然后通过先前介绍过的volumeComp.Render方法渲染所有添加到list里的后处理组件。
这样一来,我们就不需要重复改写RenderFeature冗杂的代码。而是简单创建一个脚本,继承PostProcessVolumeComponent,重写里面的抽象方法,在Render里自定义后处理!当然还有很多细节需要考虑,比如各种参数,材质,渲染队列,平台兼容性等等。
内置管线中学习后处理,基本上只需要涉及到shader。在SRP中,后处理是渲染管线里可以自由支配的一部分。学习过程中会自我提升很多 ,包括对渲染管线更深入的了解,对frame debug的使用,对unity提供的后处理组件内部也有更全面的认识。最后展示一下自己实现的一些效果。
展示了一些需要基本功底的后处理效果。部分效果实现起来还是挺复杂的!感谢观看。