本文是视频课程《Unity技术美术TA:Shader篇》,算是对自己学习的总结,也希望分享下所学知识~~
什么是雾?
就是颜色混合
输出颜色 = lerp ( 雾颜色,物体颜色,雾效混合因子 )
雾效混合因子和什么有关系?
1.物体离视角的距离
2.雾本身的浓度
Unity种 雾的三种实现方式
1.Linear,线性
fogFactor = (end - z) / (end -start)
start:开始距离
end:结束距离
z:深度值
2.Exp,指数
fogFactor = e ^ (-density * z)
density:雾浓度
3.Exp2,指数(效果更好,计算量更大)
fogFactor =e ^ ((-density * z) ^ 2)
Unity 中如何开启雾?
Lighting -> Envionment -> Other Settings -> Fog
Fog 是否开启雾
Mode 之前介绍的三种,参数一样
效果如下
自定义Shader 实现:
Shader "Custom/TA/Fog"
{
SubShader
{
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
//雾效的宏定义 FOG_LINEAR FOG_EXP FOG_EXP2
#pragma multi_compile_fog
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
};
struct v2f
{
float4 pos : SV_POSITION;
float fogFactor : TEXCOORD0;
};
v2f vert(appdata v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
float3 worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
float z = length(_WorldSpaceCameraPos - worldPos);
//雾效参数
// // 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;
//1.linear
#ifdef FOG_LINEAR
// factor = (end-z)/(end-start) = z * (-1/(end-start)) + (end/(end-start))
o.fogFactor = z * unity_FogParams.z + unity_FogParams.w;
#elif FOG_EXP
//2^x 等价于 e^(x*ln2)
//2^(-density / ln(2) *z) = e ^ (-density / ln(2) *z *ln2) = e^ (-density *z)
//exp2:计算2的x次方
o.fogFactor = exp2(-unity_FogParams.y * z);
#elif FOG_EXP2
//fogFactor =e ^ ((-density * z) ^ 2)
float density = (unity_FogParams.x * z);
o.fogFactor = exp2(-density * density);
#endif
return o;
}
fixed4 frag(v2f i) : SV_Target
{
fixed4 c = 1;
//雾效颜色
// fixed4 unity_FogColor;
#if defined(FOG_LINEAR) || defined(FOG_EXP) || defined(FOG_EXP2)
c = lerp(unity_FogColor, c, saturate(i.fogFactor));
#endif
return c;
}
ENDCG
}
}
}
内置函数实现
Shader "Custom/TA/FogBuildIn"
{
SubShader
{
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
//声明雾效所需要的内置变体:FOG_LINEAR FOG_EXP FOG_EXP2
#pragma multi_compile_fog
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
};
struct v2f
{
//声明顶点传入片断中的雾效插值器(fogCoord)
UNITY_FOG_COORDS(0)
float4 vertex : SV_POSITION;
};
v2f vert(appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
//在顶点着色器中计算雾效采样
UNITY_TRANSFER_FOG(o, o.vertex);
return o;
}
fixed4 frag(v2f i) : SV_Target
{
fixed4 col = 1;
//在片断着色器中进行雾效颜色混合
UNITY_APPLY_FOG(i.fogCoord, col);
return col;
}
ENDCG
}
}
}