Lens Distortion是UE4自带的一个shader插件,官网文档中就有详细实现步骤,文章的目的就是分析这个插件到底做了什么,以及如何实现自己的GlobalShader。
本文不会过度分析shader中的具体算法,只是讲解实现一个自定义GlobalShader的主要步骤,以及尽可能详细的讲解关键步骤中每一行代码的意义。
UE4官方shader插件docs.unrealengine.com首先按照官网文章的要求,一步一步做出来,直到编辑器中运行显示以下内容,代表你已经完成此插件。
下面我们来逐步分析整个过程到底是怎么回事。
1.目的:
你肯定有诸多疑惑,这到底显示的是个啥,这个插件该咋用呢?这个shader的目的是什么?从效果上来看,这不就是个小号的不怎么方正的矩形嘛。
其实不难理解,RT_00这张纹理图存储的是uv的偏移信息,RG是修复畸变的uv偏移量,BA是产生畸变的UV偏移量。用法如下:
为什么要减去0.5再乘以2,因为贴图不能存储负数,所以在输出的时候,把负数都增加了偏移,还被缩小了两倍,所以我们使用时要把数值再加回来。
所以这个插件的目的就是输出uv偏移的纹理,实现修正畸变或者产生畸变的效果。
2.过程:
粗略构思不难得出需要做下面3步:
1.创建一个renderTarget用于接收畸变信息
2.实现一个shader算法,使我们的GPU绘制出一张uv偏移图到renderTarget上
3.利用这张图(renderTarget)在Material编辑器中实现畸变效果
最复杂的肯定是第二步,插件中几乎所有的代码都围绕第二步展开。
下面我们来一步步分析插件的代码:
01.这是官方文章末尾的一张图,演示插件的用法,不难看出,它调用了DrawUVDisplacementToRenderTarget函数,此函数接收一堆算法的参数和UTextureRenderTarget2D类型的引用,即我们先前创建的RT_00。
打开EnginePluginsCompositingLensDistortionSourceLensDistortionClassesLensDistortionBlueprintLibrary.h,便可看到这个函数具体定义和实现。让我们转到函数实现,如下图所示:
注意:让我们暂时忽略其他算法参数,只关注OutputRenderTarget,看看这个OutputRenderTarget到底经历了怎么样的变化,变成了开篇那张图那样。
此函数很简单,只是简单调用CameraModel.DrawUVDisplacementToRenderTarget函数,转到DrawUVDisplacementToRenderTarget函数实现,前面都是一些算法参数的定义与计算,我们暂且忽略,直接翻到函数底部,这里才是真正干活的入口:<