Unity Shader:雾的数学运算以及在Unity中使用Global Fog

发表于2018-10-30
评论0 5.8k浏览
Unity 自带的 GlobalFog 通过一个屏幕特效实现了全局雾效,但其实shader的雾的效果,还会用到一些数学知识,这篇我们就来看看雾的数学运算以及Global Fog的全局雾效。

不同情况下的雾的效果:
Forward,MSAA,Bloom,Global Fog/Exponential Squared/Density 0

Forward,MSAA,Bloom,Global Fog/Exponential Squared/Density 0.045

Forward,MSAA,Bloom,GlobalFog/ExponentialSquared/Density0.085

Forward,MSAA,Bloom,GlobalFog/ExponentialSquared/Density0.125

1、雾的数学运算

雾中存在着雾粒子,当光线接近雾粒子时,有一定几率被雾粒子吸收并被散射至其他方向,在此过程中光的初始颜色将会递减,并递增雾粒子的颜色,此种大面积的散色最终产生了雾中朦胧的效果。

左侧光线的原始颜色称为Color-enter, Center,右侧最终变化后的颜色称为Color-leave,Cleave。每当Center接触一个雾粒子时,它的颜色发生如下变化:

当发生多次散射时:


Cleave=(Center-Creduction+Cincrease)-Creduction+Cincrease
由之前公式可总结出:…-Creduction+Cincrease=…*g+(1-g)*Cfog
因此

可归纳为:

如果将Cleave理解为最终可视颜色,Center为物体本身颜色,那么:

一个幂函数可以指数函数重写:

因此
将x取2以发挥GPU中log2()和exp2()函数的性能优势

此即为模拟‘均匀雾’的最终公式,exp_2(-(-log_2(g))*z))称为雾的因子f,-log_2(g)称为雾的浓度d,z称为雾的距离z。d取反后保证了公式正确逻辑,既当d增加时f将会衰减,也既是Center衰减,Cfog增加。

2、雾在Unity中的应用(Global Fog)

在以个充满雾的环境中,一个无限远的天空是无法被看见的,既是f=exp2(?d?∞)=0f=exp2(?d?∞)=0,因此正常的天空盒在有雾的场景中并不适用。可以用几个plane包围住场景,配合Unity的Global Fog充当天空盒的角色。

plane的材质用default即可,如有特殊需要也可使用其他,但shader必须在片段着色器内使用UNITY_APPLY_FOG函数。
将平行光颜色改为Cfog颜色。
进入windows/lighting/settings;找到Other Settings,勾选“Fog”,Mode改为”Exponential Squared”。
Main Camera增加Global Fog脚本。
在任意脚本中动态增减RenderSettings.fogDensity。

效果:


来自:https://blog.csdn.net/liu_if_else/article/details/73743706

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引