技术美术TA之雾效

本文是视频课程《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
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值