翻译14 Fog

Posted baolong-chen

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了翻译14 Fog相关的知识,希望对你有一定的参考价值。

应用雾到游戏对象
基于距离或深度的雾
支持deferred fog

1 Forward Fog

在14之前,一直假定着光线在真空中传播,在真空中可能是精确的。但是当光线穿过大气或水就不一样了,光线在击中物体表面时会发生被吸收、散射和反射。

一个精确的大气干扰光线渲染将需要及其昂贵的体积测量方法,那是大多数现代GPU负担不起的。相反,勉强采用一些常量雾参数近似模拟。

1.1 Standard Fog

Unity光照设置包含了场景雾设置选项,默认是不启用。启用后,默认是灰色雾。Unity自带的雾只适用于使用了Forward渲染路径的物体。若激活Deferred path,提示:

技术图片

图1 deferred 提示

技术图片

图2 不明显的雾

1.2 Linear Fog

图2不明显,是因为Fog color灰色雾将散射和反射更多的光线,吸收较少。把Fog Color改为纯黑色试试

技术图片

 技术图片

图3 linear fog

Linear Fog Mode:雾的浓度是随视距线性增长的,在视距开头正常显示,超过这个距离就只有雾的颜色可见。

线性雾公式:

技术图片

c 是雾坐标;
S 是视距起始距离;
E 是视距终止距离;
f值 被限定在[0, 1]范围,被用在雾和物体着色之间插值。

最终计算在fragment color着色到物体对象上,雾不会影响到skybox

1.3 Exponential Fog

更接近真实感的雾

技术图片 

技术图片

图4 指数雾

指数雾公式:

技术图片技术图片

d 是fog的密度因子;
c 是距离因子

1.4 Exponential Squared Fog

技术图片

技术图片

图5 指数平方雾

指数平方雾公式:

技术图片 技术图片

1.5 Adding Fog

增加Fog到自己的shader中,增加Fog需要使用内置关键字:multi_compile_fog指令。该指令会额外增加:FOG_LINEAR、FOG_EXP、FOG_EXP2变体。

#pragma multi_compile_fog

新增ApplyFog()函数,用于在Fragment计算最终着色:获取当前颜色和插值数据作为参数,返回最终颜色。

计算步骤:
任何雾公式都是基于视距的,首先计算出视距值备用;
然后使用UnityCG.cginc宏UNITY_CALC_FOG_FACTOR_RAW根据具体雾公式计算出雾因子。
最后根据雾因子,在fog_color和当前color取插值返回。

float4 ApplyFOG(float4 color, Interpolators i)
{
    float viewDistance = length(_WorldSpaceCameraPos - i.worldPos);
    UNITY_CALC_FOG_FACTOR_RAW(viewDistance);
    return learp(unity_FogColor, color, unityFogFactor);
}
技术图片
//宏UNITY_CALC_FOG_FACTOR_RAW
#if defined(FOG_LINEAR)
    // factor = (end-z)/(end-start) = z * (-1/(end-start)) + (end/(end-start))
    #define UNITY_CALC_FOG_FACTOR_RAW(coord) float unityFogFactor = (coord) * unity_FogParams.z + unity_FogParams.w
#elif defined(FOG_EXP)
    // factor = exp(-density*z)
    #define UNITY_CALC_FOG_FACTOR_RAW(coord) float unityFogFactor = unity_FogParams.y * (coord); unityFogFactor = exp2(-unityFogFactor)
#elif defined(FOG_EXP2)
    // factor = exp(-(density*z)^2)
    #define UNITY_CALC_FOG_FACTOR_RAW(coord) float unityFogFactor = unity_FogParams.x * (coord); unityFogFactor = exp2(-unityFogFactor*unityFogFactor)
#else
    #define UNITY_CALC_FOG_FACTOR_RAW(coord) float unityFogFactor = 0.0
#endif

//宏UNITY_CALC_FOG_FACTOR
#define UNITY_CALC_FOG_FACTOR(coord) UNITY_CALC_FOG_FACTOR_RAW(UNITY_Z_0_FAR_FROM_CLIPSPACE(coord))

//unity_FogParams 定义在ShaderVariables
// x = density / sqrt(ln(2)), useful for Exp2 mode
// y = density / ln(2), useful for Exp mode
// z = -1/(end-start), useful for Linear mode
// w = end/(end-start), useful for Linear mode
float4 unity_FogParams;
View Code

注意雾因子必须限定在[0,1]

return learp(unity_FogColor, color, saturate(unityFogFactor));

同时雾也不能影响Alpha值

color.rgb = learp(unity_FogColor.rgb, color.rgb, saturate(unityFogFactor));

技术图片

图6 linear:standard vs. mine

技术图片

图7 exp:standard vs. mine

技术图片

图8 exp2:standard vs. mine

1.6 Depth-Based Fog

与Standard Shader不同的原因是计算fog坐标方法不同。虽然使用world-space视图距离是有意义的,但标准着色器使用裁剪空间深度值。因此视角不影响雾坐标。此外,在某些情况下,距离是受相机的近裁切面距离的影响,这将把雾推开一点。

技术图片

图9 深度 (三角) vs. 距离(园)

使用深度代替距离优点是:不必计算平方根,计算速度更快,适用于非真实渲染。缺点是:忽略视角,也即相机原点会影响雾密度,因为旋转时密度会改变。

技术图片

图10 红到蓝旋转,深度改变密度



1.7 Depth or Distance

1.8 Disabling Fog

1.9 Multiple Lights

2 Deferred Fog

2.1 Image Effects

2.2 Fog Shader

2.3 Depth-Based Fog

2.4 Fixing the Fog

2.5 Distance-Based Fog

2.6 Calculating Rays

2.7 Deriving Distances

2.8 Fogged Skybox

2.9 No Fog

以上是关于翻译14 Fog的主要内容,如果未能解决你的问题,请参考以下文章

ubuntu 14.04 set up fog 0.32

如何将此 JavaScript 代码片段翻译成 Parenscript?

初步了解Panda3D 雾(Fog)

VSCode自定义代码片段14——Vue的axios网络请求封装

VSCode自定义代码片段14——Vue的axios网络请求封装

VSCode自定义代码片段14——Vue的axios网络请求封装