本文主要分享虚幻四中着色器的使用技巧与如何添加自己的着色模型的方式。
(正在设计的一个像素风格的渲染流程,同样采用本文的方法,对引擎的着色模型进行了改造,可以接受天光/点光等的自定义照明效果)
鄙人消失了一个月左右,又回来了,对此深感抱歉。之前因为学业/事业/身体/等各种原因,之前的系列文章也中断了一段时间~之前应该是讲到了流体的部分,由于数学性/图形学性较强,鄙人也还在准备当中。
本周先插播一小段技巧,同样也是实用的技巧,希望能够分享给大家。
二.材质中的伪体素
三.在虚幻四中基於NS方程的流體模擬
2.NS方程的解析和实际模拟
四.metaball 的原理与在材质中的实现
五.在虚幻四中 path tracing
1.相机内参、简单物体变换信息的处理
2.path tracing的解析,temporal的思路
3.在材质中进行path tracing
六、透明物体的渲染/造假技巧
特别篇目:
一、NPR与虚幻四的着色模型(本文)
二、一些后期处理的原理与解析
本文的目标:在虚幻四中插入自定义的着色模型,理解虚幻四中延迟渲染的流程。鄙人仅仅分享一种简单的做法,不代表最优做法/官方做法,分享仅此为了让一些很多人都存在的疑问得以解决。
(Cel Shading,对全部光源都适用的(而不是在材质编辑器里只能通过蓝图手动传入的那种。。。))
文章结构:
一.GBuffer的结构
二.虚幻中Shader.usf的内部关联
三.插入自定义着色模型
一.GBuffer的结构
虚幻四大多时候使用延迟渲染,而前向/延迟渲染的最大区别,可能就是GBuffer的使用与否。
GBuffer,全称Geometry Buffer,事实上这个定义很早被定下,而实际上如今的意思已经远超原本的意思(虽然这个东西不重要,还是稍微提一下)
这里将解析一下虚幻四默认的GBuffer的结构。
首先,需要了解虚幻四延迟渲染的流程。
GBuffer的本质是送信者,将信息传递给最终的着色部分。而实际上信息提供者是Mesh,把信息给送信者的是材质,也就是说,材质是中介的中介(可能有点绕了)。
换句话说,虚幻的普通域的材质实际上写入的是GBuffer,而不是最终结果。
其次,再整理一下各种东西之前的关系。
A:场景物体
B:材质/材质编辑器输出
C:BassPixelPass(后面会提到
D:GBuffer
E:FinalPixelPass(最终根据各种着色模型输出到屏幕的Pass
渲染顺序一般为
A->B->C->D->E
最后,稍微提一下虚幻四中默认的GBuffer的排布.
本文旨在插入“新的”着色模型,基本的DiffuseColor/SpecularColor/Metalic/Specular/AO/WorldNormal什么的不再具体阐述(毕竟需要修改的地方很少,默认的即可。)
在不知道什么版本更新了Cloth/Eye/ClearCoat 的着色模型之后,GBuffer里多了一个八位四通道的的CustomData,也就是说,这个CustomData是可以被使用而不影响原有的渲染流程的。接下来,鄙人将分享一下,怎么插入自定义的着色模型,和利用这个插槽来增加参数。
GBuffer.CustomData
(他在shader里的出现形式是这样的)
虚幻四自带的Cloth/Hair/Eye/ClearCoat等着色模型均使用了该CustomData,来储存切线或者其他参数。
二.虚幻中Shader.usf的内部关联
前面做了一些铺垫,虚幻的材质系统在内部是有很大关联的。鄙人将介绍几个常用的usf文件,理解文件结构,也为后面增加着色模型提供了一些理论基础。
首先打开引擎源目录,找到Engine/Shaders文件夹(建议备份一份)
(4.18左右的版本里面还分了Private/Public/StandaloneRenderer的文件夹)
里面有很多文件,选几个解析一下其作用与各种关联。
这里需要有一点点编程基础(#include什么的,#if什么的指令需要清楚)
下面正文
1.BRDF.usf(BRDF.ush)
里面储存了大部分常用的brdf函数(大雾:抄过的人都说好)
因为里面应有尽有,只有想不到的,没有找不到的,在写着色模型的时候也能很轻松地调用,因此不详细解说了。
(其中一个Diffuse的BRDF,很方便shader学习者借鉴,因为上面有论文出处)
2.BasePassPixelShader.usf
控制写入GBuffer的着色器。可以读取材质编辑器里输出的参数,可以控制GBuffer里应该写入什么。
比如材质编辑器里指定了着色模型A,这个Pass可以控制把材质中的diffusecolor写入到normal里,把specular写入到ao里,大概就是这个意思。也就是说,这里再次说明了材质只是中介的中介,不管材质的输出是怎么连的,最后决定怎么写入GBuffer的都是这个shader。
3.DeferredLightingCommon.usf(DeferredLightingCommon.ush)
这个文件顾名思义,就是控制光照的。其中最重要的函数是GetDynamicLighting,这里控制了对于每种光源/每种表面,着色器应该怎么处理。添加着色模型也应该从这里入手。
4.ShadingModels.usf(ShadingModels.ush)
被3. include了。主要函数是SurfaceShading 等一系列决定最终光照的函数。
里面根据GBuffer里储存的ShadingModel,在case SHADINGMODELID_XXXXXX 里进行了着色模型的选择。
同时,这个文件里是最终决定着色方式的著色器。
他们的执行顺序(按理来说)应该是:2->3->4->1
三.插入自定义着色模型
首先来一个简单的例子:
在ShadingModels.usf(ShadingModels.ush)中找到StandardShading函数,这个函数被SurfaceShading 当着色模型为默认时调用。
其中有三行:
float3 Diffuse = Diffuse_Lambert( DiffuseColor );
//float3 Diffuse = Diffuse_Burley( DiffuseColor, LobeRoughness[1], NoV, NoL, VoH );
//float3 Diffuse = Diffuse_OrenNayar( DiffuseColor, LobeRoughness[1], NoV, NoL, VoH );
可以通过注释更改默认的Diffuse的BRDF。
对于高光也可以进行一样的操作,当然前提是读者对shader十分熟悉了,自然替换起来也可以得心应手。
关于添加/插入自己的着色模型。
提供两种方案
1.通过C++增加材质编辑器里的着色模型选项,然后再通过shader增加真正的shadingmodel
2.直接去掉虚幻默认的shadingmodel,更改为自己的。
拿ClearCoat举例,在材质中选择ClearCoat可以开多三个口:
透明图层,透明图层粗糙度,还有最后的BottomNormal。
先从BasePassPixelShader.usf开始
找到#elif MATERIAL_SHADINGMODEL_CLEAR_COAT
然后就可以决定这些接口将怎么被写入GBuffer中。
GBuffer.CustomData.xy = ClearCoatBottomNormal0(MaterialParameters).xy;
GBuffer.CustomData.z = GetMaterialCustomData0(MaterialParameters);
GBuffer.CustomData.w = GetMaterialCustomData1(MaterialParameters);
就像这样,写入到Custom的xy就是BottomNormal的xy值,写入到Custom的z的就是材质输出的透明图层,以此类推。
然后到ShadingModels.usf(ShadingModels.ush) 中找到SurfaceShading ,可以看到类似的根据着色模型ID选择着色模型的代码。新建一个函数XX(FGBufferData GBuffer),
在case SHADINGMODELID_CLEAR_COAT:
后调用自己的函数。
XX(GBuffer);
然后就可以在这个函数里为所欲为了。
关于NPR的着色器可以参考底下:
这里我给出一个自己改进过的经验模型,也就是题图的着色模型的Diffuse部分:
(暂且命名为Diffuse_YCZ函数)
这个函数是基于CelShading的,加入了一个Hardness这个参数,来控制分界边的软硬。
注:Hardness需要为整数。这种办法可以使CelShading退化至普通的Lambert,对于边界的锯齿也能更好地去除。
(将GBuffer里除了法线之外的插槽全部改为了自定义的参数,如控制多颜色的Instance,控制阴影,等)
使用这种办法可以快速加入自己需要的着色模型,相当于定制自己的引擎,比修改源码重新编译应该要来得更靠谱一点,从成功几率上看。
本期文章要分享的东西也写完了~希望能帮到各位虚幻四的用户和读者。
下一期将会简单地介绍一下一些后期处理在虚幻四中的实现方法。
包括NPR的Hatching,描边,还有水面分界特效的简单实现方法。
(Hatching与描边)
(动态水面分界)
https://www.zhihu.com/video/913096339934576640
大家的点赞才是我最大的前进的动力~所以 阅读完之后记得点赞哦(๑•̀ω•́ ๑)
文章仅仅为了分享经验交流心得,抛砖引玉,见笑大方了。如有纰漏,望斧正。
参考文献/项目: