-
Notifications
You must be signed in to change notification settings - Fork 0
Exponential Height Fog
计算一个雾的比例,设定雾的颜色,对于每个着色点,最终颜色按照下式计算:
col.rgb = col.rgb*fogInscatteringAndOpacity.a + fogInscatteringAndOpacity.rgb;除了雾以外,太阳光也会对雾有影响,所以需要叠加directionalInscattering。
fogColor = _FogColor.rgb*(1-expFogFactor) + directionalInscattering;输入:fov、aspect、near
输出:frustumCorners(Matrix4x4)

输入:深度纹理(0~1空间),相机世界坐标
输出:每个片元对应的世界坐标
worldPos = _WorldSpaceCameraPos + linearDepth * rayDir;主要思想是传输方程,由于有介质,每个像素的着色为原始着色点的颜色*透光率+光线在介质中的积分。

为了性能考虑,在UE中使用beer定律对raymarching进行近似(光线均匀穿过介质的时候,亮度呈指数衰减)。
雾(exclusionIntersection)的起始密度:
exponent = max(-127.0f,_HeightFallOff*(exclusionIntersectionY-_StartY));
rayOriginalTerms = _FogDensity * exp2(-exponent);光学厚度(透光率公式的指数)
falloff = _HeightFallOff* rayDirectionY;
//(rayDirectionY是startDistance点和着色点的高度差,散射理论的名称叫光学厚度,是一个关于σt的积分。)透光率 = exp2(-falloff)/falloff; Li = rayOriginalTerms*(1-透光率)*rayLength
_FogDensity:雾的全局密度
_FogColor:雾的颜色
_StartY:雾起始高度
_EndY:雾的终止高度
_HeightFallOff:高度衰减系数
_StartDistance:雾距离相机的起始距离
_MinFogOpacity:最小透光率(不能让场景的某处全被遮盖住)
介质会被光照亮,因此除了自己本身的颜色以外,要加上光的颜色。同样是沿着介质进行积分,同样使用beer定律进行近似。
注意inscatter的计算与视线和直射光的夹角相关。
inscatter= _LightColor0 * pow(dot(normalize(cameraToReceiver),_WorldSpaceLightPos0), _InScatteringExponent);_LightColor0:直射光颜色
_WorldSpaceLightPos0:直射光方向
_InScatteringExponent
_DirectionalInscatteringStartDistance:被照亮的起始距离
Engine\Shaders\Private\HeightFogVertexShader.usf
Engine\Shaders\Private\HeightFogPixelShader.usf
Engine\Shaders\Private\HeightFogCommon.ush