Unity中Shader雾效的实现方法一


前言

Unity中Shader雾效的实现方法一,按照之前的公式, 我们自己来实现一下

基于上一篇文章继续:


一、在片元着色器中使用如下公式计算

最终的颜色 = lerp(雾效颜色,物体颜色,雾效混合因子)

不管是什么类型的雾,这个雾效的公式都是统一的

1、获取雾效颜色

unity_FogColor

2、物体的颜色一般通过纹理采样得到,此处用 1 代替测试

3、获取 雾效混合因子(由 雾的距离 和 雾的浓度决定)

雾效混合因子是由,之前的三个雾效衰减公式计算得到的

因为在片元着色器中计算雾效需要使用该因子
所以在 v2f 中定义一个 TEXCOORD 类型的 float 变量 fogFactor

float fogFactor : TEXCOORD1;


二、在顶点着色器中,计算不同类型的雾效混合因子(在顶点着色器计算节省性能)

Unity预定义好方便我们计算的四维变量 unity_FogParams

在这里插入图片描述

1、计算线性雾的雾效混合因子

在这里插入图片描述

  • 获取 z :这个z是摄像机到物体的距离
    z = (用摄像机的世界坐标 - 顶点的世界坐标)的 模长
    计算需要准备:
    摄像机的世界坐标:_WorldSpaceCameraPos
    顶点的世界坐标:mul(unity_ObjectToWorld,v.vertex)

float z = length(_WorldSpaceCameraPos - worldPos);

  • 获取 start 和 end
    上面的公式可以等价为:
    fogFactor
    = (end - z) / (end - start)
    = (end / (end - start)) + z * (-1 / (end - start))
    使用Unity预定义的公式后:
    = unity_FogParams.w + z * unity_FogParams.z ;

//(end - z) / (end - start)= (end / (end - start)) + z * (-1 / (end - start))
o.fogFactor = z * unity_FogParams.z + unity_FogParams.w;

效果:
请添加图片描述

2、计算指数雾1 的雾效混合因子

在这里插入图片描述

fogFactor
= exp2(-density * z)
使用Unity预定义的公式后:
= exp2(-unity_FogParams.y * z)

//exp2(-density * z)
o.fogFactor = exp2(-unity_FogParams.y * z);

效果:
请添加图片描述

3、计算指数雾2 的雾效混合因子

在这里插入图片描述
fogFactor
= exp2(-(density * z)^2)
使用Unity预定义的公式后:
= exp2(-(unity_FogParams.x * z)^2)

//exp2(-(density * z)^2)
float density = unity_FogParams.x * z;
o.fogFactor = exp2(-density * density);

效果:
请添加图片描述


三、最终测试代码

//unity的雾效
//雾效的实现方法一
Shader "MyShader/P1_9_3"
{
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        
        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma multi_compile_fog
            #include "UnityCG.cginc"
           

            struct appdata
            {
                float4 vertex : POSITION;
            };

            struct v2f
            {
                float4 vertex : SV_POSITION;
                float fogFactor : TEXCOORD1;
            };
            
            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                float4 worldPos = mul(unity_ObjectToWorld,v.vertex);
                float z = length(_WorldSpaceCameraPos - worldPos);

                #if defined(FOG_LINEAR)
                    //(end - z) / (end - start)= (end / (end - start)) + z * (-1 / (end - start))
                    o.fogFactor = z * unity_FogParams.z + unity_FogParams.w;
                #elif defined(FOG_EXP)
                    //exp2(-density * z)
                    o.fogFactor = exp2(-unity_FogParams.y * z);
                #elif defined(FOG_EXP2)
                    //exp2(-(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 = 0;
                #if defined(FOG_LINEAR) || defined(FOG_EXP) || defined(FOG_EXP2)
                    c = lerp(unity_FogColor,c,i.fogFactor);
                #endif
                
                return c;
            }
            ENDCG
        }
    }
}

Unity,我们可以使用Shader实现各种效果,包括雾效模拟。雾效模拟可以让场景的物体看起来更立体,增强深度感。 实现雾效模拟的Shader需要使用到Unity内置的全局变量和函数,具体步骤如下: 1. 在Shader一个属性,表示雾的颜色。 ``` Properties { _FogColor ("Fog Color", Color) = (1, 1, 1, 1) } ``` 2. 设置着色器的渲染模式为透明。 ``` Tags { "Queue"="Transparent" "RenderType"="Transparent" } ``` 3. 在Shader一个片元着色器函数,并在该函数计算出雾的强度。 ``` fixed4 frag (v2f i) : SV_Target { // 计算相机到片元的距离 float depth = UNITY_ACCESS_DEPTH(i.uv); float distance = LinearEyeDepth(depth); // 计算雾的强度 float fogDensity = distance * _FogDensity; float fogFactor = 1.0 - exp(-fogDensity * fogDensity); // 计算最终颜色 fixed4 col = tex2D(_MainTex, i.uv) * i.color; return lerp(col, _FogColor, fogFactor); } ``` 在上面的代码,我们首先计算相机到片元的距离,然后根据距离和雾的密度计算出雾的强度,最后使用lerp函数将雾的颜色和物体的颜色进行插值,得到最终的颜色。 4. 在Unity创建一个材质,并将上述Shader应用到该材质上。 5. 将该材质应用到场景的物体上,即可看到雾效果的模拟。 以上就是在Unity实现雾效模拟的基本步骤。需要注意的是,雾效模拟需要耗费一定的计算资源,因此在实际应用需要根据场景的复杂度和设备性能进行调整。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

楠溪泽岸

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值