车漆渲染做法Clear-Coat

文章详细介绍了ClearCoat透明涂层渲染技术,包括其BRDF模型、参数设定、GLSL代码实现,以及在UE4中延迟渲染和前向渲染的差异与实现方法。针对基础层的修改和能量损失计算也进行了讨论,并提出了在低配移动设备上采用MatCap的解决方案。
摘要由CSDN通过智能技术生成

什么是ClearCoat

clearcoat指的是透明图层模型。PBR等标准材质模型等适合描述单层的,各项同性的材质表面。但实际上现实中多层材质相当普遍,常见的表面上有一层薄薄的透明涂层的材质,比如透明车漆,家具上的透明薄膜。
在这里插入图片描述
我们可以在标准材质模型上添加第二个镜面反射来模拟透明图层(也就是添加第二个镜面反射BRDF项)。为了简化实现复杂度,我们假定透明涂层是各项同性的非金属。我们把原来的基础材质层称为base layer,再添加一层ClearCoat层反射。如图所示。
在这里插入图片描述

ClearCoat镜面反射的BRDF

原理上来说,ClearCoat的BRDF双向反射函数模型和标准PBR的结构没有什么区别。
但为了节省计算,DFG项会使用代价更小的实现公式。

D项会采用GGX

G项会采用Kelemen01提出的38式,Kelemen的可见项V的实现
在这里插入图片描述在这里插入图片描述

F项会采用Schlick
假定透明涂层是由聚氨酯(常用于清漆)构成的,光线从空气入射聚氨酯的折射率(IOR)为1.5,由此我们可以计算出透明涂层的f0值
在这里插入图片描述可以看出透明涂层的反射率和常见非金属材质的反射率一样都是4%。

最后,我们把透明图层的BRDF项一起整合添加

在这里插入图片描述
(这个fc的BRDF包不包括F项呢?据我分析:fd代表diffuse)
注:(38)(39)(40)等代表引用书中的公式,第38,第39,第40个公式,不作为公式的一部分。

透明涂层的参数设定

透明涂层模型支持我们之前定义的标准模型的所有参数。它本身额外定义了下表中的两个参数。
参数定义
ClearCoat透明涂层的强度。标量,取值范围0到1
ClearCoatRoughness透明涂层的感知粗糙度。标量,取值范围0到1
ClearCoatRoughness参数使用和Roughness参数一样的方式进行重映射。
在这里插入图片描述

透明图层的GLSL实现代码(伪代码)

void BRDF(){
     //从标准模型计算Fd和Fr
    //重映射和线性化Roughness
    clearCoatPerceceptualRoughness=clamp(clearCoatPerceceptualRoughness,0.089,1.0);
    clearCoatRoughness=clearCoatPerceceptualRoughness*clearCoatPerceceptualRoughness;

    //clear coat BRDF
    float Dc=D_GGX(clearCoatRoughness,NoH);
    float Vc=V_Kelemen(clearCoatRoughness,LoH);
    float Fc=F_Schlick(0.04,LoH)*clearCoat;     //clear coat strength
    float Frc=(Dc*Vc)*Fc;

    //考虑Base层的能量损失,据我分析,Fr是基础的镜面反射BRDF,Fd是Diffuse
    return color*((Fd+Fr*(1.0-Fc))*(1.0-Fc)+Frc);
}

ClearCoat对基础层的修改

加入透明图层后,基础层原来的光线从空气到材质的反射率f0需要换成从透明图层到基础层的反射率。
为此,我们可以先用基础层原来的f0计算出光线从空气入射基础层的折射率(IOR),然后结合透明图层的折射率(IOR)1.5计算出新的基础层f0值。
注:反射率f0是BRDF中F项的参数
在这里插入图片描述

UE4中ClearCoat实现的分析

PC端延时渲染下的实现
在UE4根据宏开关MATERIAL_SHADINGMODEL_CLEAR_COAT判断是否开启了ClearCoat光照模型,
在ShadingModelsMaterial.ush中通过GetMaterialCustomData0(MaterialParameters)获得蓝图中ClearCoat参数,
填充到GBuffer.CustomData结构体中,然后再填充进OutGBufferD中。

然后通过GBUFFER_HAS_PRECSHADOWFACTOR宏开关,传递给MRT[5/4]通道中,默认是4
在这里插入图片描述
传给G-Buffer以后,开始计算光照,其实就是对G缓存中的图像合成过程。
最终在ReflectionEnvironmentPixelShader.usf文件中把关于ClearCoat高光部分的GBuffer整合。具体代码如下:
在这里插入图片描述
主要就是这两个部分对ClearCoat进行了计算。
首先是重映射RemapClearCoatDiffuseAndSpecularColor,这部分应该是计算Base层的能量损失。代码如下:
在这里插入图片描述
然后是ReflectionEnvironment函数,首先Color为采样的CubeMap或者平面反射+SSR,根据ClearCoat强度插值,方便下一步使用。
具体代码如下:
在这里插入图片描述
请添加图片描述
简单分析下,首先采样了一张预计算的LUT图用来拟合环境光部分的DGF项,节省计算量,然后最终ClearCoat的输出结果为SSR+GatherRadiance+GatherRadiance(叠加了两次)
不开启ClearCoat的输出结果为左图,开启了ClearCoat的输出结果为右图
由于是GBuffer的合并,这一步最后的结果会叠加到SV_Target上。Blend One One模式

与PC端前向渲染的区别
切换到前向渲染后,效果差距很大,经过调试分析出以下几点
1,默认前向没有SSR,默认延时有SSR(影响不是特别大)
2,前向渲染的效果和标准PBR的SpecularIBL几乎一致,感觉并没有叠加第二遍运算。
请添加图片描述

最终工作:修改ForwardLighting支持ClearCoat

修改项一:SpecularIBL部分

在前向渲染BassPassPixelShader中,关于IBL的计算只计算了一次,并没有叠加第二次。所以我们需要叠加第二次IBL的计算。
请添加图片描述
forward修改后:
请添加图片描述

修改项二:基础层部分的干扰

通过分析ClearCoat的光照模型可以得知,加了一层透明薄膜层会对基础层的DiffuseColor和SpecularColor造成影响,但是在Forward里并没有发现对于这部分的影响,所以我们需要加上。
请添加图片描述
forward修改后:
请添加图片描述
修改项三:
全部移植过去后,仍发现效果有些对不上,经过一步步调试,发现关于Capture和cubemap的Blend混合结果这部分出现了问题,IBL叠加后效果不对。
REFLECTION_COMPOSITE_USE_BLENDED_REFLECTION_CAPTURES
为了工作效率,简单粗暴的直接开启了这部分计算。
请添加图片描述

至此,关于Forward前向渲染支持ClearCoat工作到此结束。

Mobile端延时渲染下的实现

经分析,Mobile端效果和deferred效果基本一致,就不做过多分析

低配Mobile端延时渲染下的实现
准备采用MatCap

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值