11_添加边缘光
添加边缘光
新增参数
对应的分别为屏幕空间高光开关,皮肤ID,光源颜色,边缘光染色,屏幕空间下边缘光宽度,阈值,衰减程度,强度
宏开关声明
参数声明 
相关宏函数增加
方便后续计算添加了pow宏函数 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#define DEFINE_POW(TYPE) \
TYPE pow2(TYPE x) { return TYPE(x * x);} \
TYPE##2 pow2(TYPE##2 x) { return TYPE##2(x * x);} \
TYPE##3 pow2(TYPE##3 x) { return TYPE##3(x * x);} \
TYPE##4 pow2(TYPE##4 x) { return TYPE##4(x * x);} \
TYPE pow3(TYPE x) { return TYPE(x * x * x);} \
TYPE##2 pow3(TYPE##2 x) { return TYPE##2(x * x * x);} \
TYPE##3 pow3(TYPE##3 x) { return TYPE##3(x * x * x);} \
TYPE##4 pow3(TYPE##4 x) { return TYPE##4(x * x * x);} \
TYPE pow4(TYPE x) { TYPE xx = x * x; return TYPE(xx * xx);} \
TYPE##2 pow4(TYPE##2 x) { TYPE##2 xx = x * x; return TYPE##2(xx * xx);} \
TYPE##3 pow4(TYPE##3 x) { TYPE##3 xx = x * x; return TYPE##3(xx * xx);} \
TYPE##4 pow4(TYPE##4 x) { TYPE##4 xx = x * x; return TYPE##4(xx * xx);} \
TYPE pow5(TYPE x) { TYPE xx = x * x; return TYPE(xx * xx * x);} \
TYPE##2 pow5(TYPE##2 x) { TYPE##2 xx = x * x; return TYPE##2(xx * xx * x);} \
TYPE##3 pow5(TYPE##3 x) { TYPE##3 xx = x * x; return TYPE##3(xx * xx * x);} \
TYPE##4 pow5(TYPE##4 x) { TYPE##4 xx = x * x; return TYPE##4(xx * xx * x);} \
TYPE pow6(TYPE x) { TYPE xx = x * x; return TYPE(xx * xx * xx);} \
TYPE##2 pow6(TYPE##2 x) { TYPE##2 xx = x * x; return TYPE##2(xx * xx * xx);} \
TYPE##3 pow6(TYPE##3 x) { TYPE##3 xx = x * x; return TYPE##3(xx * xx * xx);} \
TYPE##4 pow6(TYPE##4 x) { TYPE##4 xx = x * x; return TYPE##4(xx * xx * xx);}
DEFINE_POW(bool)
DEFINE_POW(uint)
DEFINE_POW(int)
DEFINE_POW(float)
DEFINE_POW(half)
对皮肤部分进行区分
因为这里处理为皮肤和服装的背光强度是不一样的,所以进行划分,这里直接指定材质ID是皮肤
因为本来材质划分就只有5个,所以S0~S4就是材质ID,而最后一个则是空,表示这个部位没有皮肤部分 
计算相关衰减项
背光衰减
因为边缘光是根据视线方向和灯光方向来控制的,比如说背光的时候边缘光会很强,而面光面就比较弱。所以先计算LOV 这里对(-LOV)进行了重映射,映射到0~1,这里注意是(-LOV),因为LOV根据点乘特征同向为一反向为-1,所以面光面为1,背光面为-1,而边缘光应该以背光面为主,所以取(-LOV)计算,得到viewAttenuation
这里得到viewAttenuation后还做了额外的处理,先进行平方后在乘0.5和加0.5,相当于平滑过渡,同时也是为了面光面也有边缘光为0.5,不为0,下面的函数图可以更好理解
函数图 
法线垂直方向衰减
这里取法线的Y方向,也就是垂直的方向,重映射到0~1
verticalAttenuation
这里对皮肤和服装部分进行区分,让服装的强度低一点直接进行平方,最后整体进行平滑处理
可以看到皮肤部分没有什么变化,衣服部分被压暗了一下,也可以理解为增加对比度,衰减增强了 
兰伯特方向衰减
其实就光源对于模型的衰减,也适用于边缘光。这里因为之前计算过投影,所以也追加进去

菲涅尔衰减
这一步是真正求边缘光的步骤,一般边缘光都是通过菲涅尔进行计算。因为这里需要对相机距离进行反馈,所以先计算相机距离
计算菲涅尔NOV
这是NOV的值,需要的边缘光是黑色部分,所以边缘光需要的值是1-NOV
对皮肤进行判断,皮肤的菲涅尔效果应该比衣服更弱,所以被(1-NOV)减去的值应该更多,然后衰减程度也和相机距离相关,min(1, cameraDistance / 12.0)最大值为1,当相机距离为12米时为最大,这里12.0就是相机距离,综合起来看就是随距离越远,菲涅尔强度略微增强(其实肉眼看不太出来)
最后根据皮肤划分进行平滑调整 
相机距离衰减
这里相当于5m之后开始逐渐衰减,5m之前不变,因为小于5的时候减去的部分是负数进行钳制就会变成0

背光中心向外围方向衰减

边缘光颜色控制
阳光颜色混色
皮肤只混合灰度,而非皮肤混合颜色
这里对阳光强度控制,先对基础颜色进行压制将颜色尽量压制到暗部,然后进行不完全的归一化,这里是对暗处提亮,而亮的地方进行压制防止过曝,前面进行压制过后暗处的地方相当于变多了,那么暗部细节就会提亮。这里其实是计算平均整体亮度,但是为了保证有一定明暗关系,所以取了0.7而不是1 
边缘光混合漫反射
不使用边缘光的地方衰减使用Albedo
边缘光使用提亮过后的漫反射颜色
这里对边缘光的漫反射强度做处理,大概是平均边缘光的强度,漫反射强度越高,边缘光减弱
曲线大致如下 
边缘光镜面反射混合
边缘光的镜面反射直接使用PBR镜面反射,使用金属度划分插值边缘光漫反射和镜面反射程度
整体控制强度,然后乘上上面计算的衰减参数和光源颜色就得到边缘光了 
边缘光染色和强度控制
对边缘光进行染色。最后对边缘光进行强度控制,效果也是平滑提亮
曲线大概如下 
屏幕空间边缘光
这里添加了屏幕空间的边缘光,和计算投影是一个原理,采样偏移的深度图与原深度图进行相减。计算最后就是乘上一个强度系数控制
最后混合输出 
当前效果

Enjoy Reading This Article?
Here are some more articles you might like to read next: