目录
前言
原理
P1
雾效分类
按表现
- 高度雾
- 深度雾
按实现方式
- 顶点雾
- 后期雾
在前向渲染中,大多使用顶点雾,即在每个场景物体进行着色的最后一步进行雾效计算,直接将混合结果输出到物体上。
而后期雾主要指通过读取buffer中的信息例如深度信息而计算雾的方式,通常用于延迟渲染等渲染管线
雾密度与相对高度呈指数相关
- 相机与顶点的高度差越小,雾密度越低
- 雾的由浓至淡的变化高度本身相对摄像机存在高度差
(如雾从海拔高度为0向海拔高度为400m逐渐稀薄,但是摄像机在海拔200m的位置,则高度差为-200m)
为使雾浓度更加可控,提供全局密度参数_GlobalDensity 与高度差参数_FogHeight
FogDensity = _GlobalDensity * exp2(_WorldSpaceCameraPos.y - posWorld.y - _FogHeight)
雾密度 = 全局密度 * 2^(相机高度-目标位置高度-雾变化高度范围相对摄像机的高度差)
为便于控制,给予参数_FogFallOff参数,对雾的指数变化进行控制
falloff = _FogFalloff * (posWorld.y-_WorldSpaceCameraPos.y-_FogHeight)
雾散强度 = 全局雾散系数 * (相机高度-目标位置高度-雾变化高度范围相对摄像机的高度差)
FogFactor = (1 - exp2(-falloff))/falloff
指数雾强度 = (1 - 2^(-雾散强度)) / 雾散强度
雾密度与相对距离相关,相机与顶点的距离越远,雾越浓,距离摄像机过近的位置应该很难看到雾,因此拟合雾与相对距离正相关,并且有一个起始变化距离
viewDir = posWorld - _WorldSpaceCameraPos;
视线向量 = 目标位置世界坐标 - 摄像机世界坐标;
rayLength = length(viewDir);
视线距离 = 视线向量长度
distanceFactor = max((rayLength - _FogStartDis) / _FogGradientDis, 0);
距离强度 = (视线距离 - 起始距离)/ 距离变化系数
雾整体浓度
fog = fogFactor * fogDensity * distanceFactor
雾浓度 = 雾强度 * 雾密度 * 雾距离强度
受光照射的顶点,其雾的颜色会受到光源颜色的影响,由于雾效是边缘模糊的低精度效果,此处光强可以使用基本光照模型进行近似。
我们在这里参考Lambert光照模型,即光强度等于顶点法线与入射光夹角,此处由于雾效生效距离较远,我们用视线方向的逆方向替代顶点法线进行计算,同时给予指数衰减参数_FogInscatteringExp进行控制
inscatteringFactor = pow(saturate(dot(-normalize(viewDir), WorldSpaceLightDir(posWorld))), _FogInscatteringExp);
散射强度 = (归一化视线向量的反方向 与 入射光方向 的夹角)^指数衰减系数
散射衰减
散射同样受距离影响
inscatteringFactor *= 1-saturate(exp2(falloff))*distanceFactor;
散射强度 *= (1 - 2^(-雾散强度)) *雾距离强度
最终颜色混合
fogColor = lerp(_FogColor, _LightColor0, saturate(inscatteringFactor));
最终雾效颜色 = 雾颜色与光源颜色的散射强度插值
P2