Unity3D Shader之伪雾化效果

bluk_ish.png

我们不使用Fog,通过Sprite 使用定制的shader 来实现上面的效果。

这个Shader主要做的事情:

在Sprite的底部叠加天空的颜色,看起来像渐渐消失。叠加的颜色强度依赖于距离相机的距离,离相机越远,则越强。

Shader如下:

// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'

Shader "Custom/2DFogSpriteShader"
 {
     Properties
     {
         [PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
         _SkyColor ("Sky Color", Color) = (1,1,1,1)
         _MaxCamDist("Max Camera distance", float) = 100
         [MaterialToggle] PixelSnap ("Pixel snap", Float) = 0
     }
  
     SubShader
     {
         Blend SrcAlpha OneMinusSrcAlpha
  
         Pass
         {
         CGPROGRAM
             #pragma vertex vert
             #pragma fragment frag
             #pragma multi_compile DUMMY PIXELSNAP_ON
             #include "UnityCG.cginc"
  
             struct appdata_t
             {
                 float4 vertex   : POSITION;
                 float4 color    : COLOR;
                 float2 texcoord : TEXCOORD0;
             };
  
             struct v2f
             {
                 float4 vertex   : SV_POSITION;
                 fixed4 color    : COLOR;
                 half2 texcoord  : TEXCOORD0;
                 float4 worldPos : TEXCOORD1;
             };
  
             v2f vert(appdata_t IN)
             {
                 v2f OUT;
                 OUT.vertex = UnityObjectToClipPos(IN.vertex);
                 OUT.texcoord = IN.texcoord;
                 OUT.color = IN.color;
                 OUT.worldPos = mul(unity_ObjectToWorld, IN.vertex);
                 #ifdef PIXELSNAP_ON
                 OUT.vertex = UnityPixelSnap (OUT.vertex);
                 #endif
  
                 return OUT;
             }
  
             sampler2D _MainTex;
             fixed4 _SkyColor;
             float _MaxCamDist;
  
            fixed4 frag(v2f IN) : COLOR
            {
                float dist = distance(IN.worldPos, _WorldSpaceCameraPos);
                half4 texcol = tex2D (_MainTex, IN.texcoord) * IN.color;
                float distFactor = saturate(dist/_MaxCamDist);
                half4 intercol = lerp(texcol, _SkyColor, distFactor);
                float gradientFactor = distFactor / 3;
                half4 finalCol = lerp(_SkyColor, intercol, (IN.texcoord.y - gradientFactor)/ (1 - gradientFactor)) * step(gradientFactor, IN.texcoord.y);
                if (IN.texcoord.y < gradientFactor) finalCol = _SkyColor;
                finalCol.a = texcol.a;
                return finalCol;
            }
         ENDCG
         }
     }
     Fallback "Sprites/Default"
 }

场景中创建若干个Sprite,并将上面的shader创建Material 赋给这些Sprite.

创建 SkyColorManager.cs ,把脚本挂在Camera上。将Camera设置为Solid Color ,通过脚本来设置Camera 背景颜色。

  • 通过Gradient 设置颜色渐变,
  • 通过 fogMat.SetColor("_SkyColor", Camera.main.backgroundColor); 将背景颜色传给上面的Shader.
  • 通过gradient.Evaluate(Mathf.PingPong(timeCounter, 1)); 使背景颜色动态变化。
public class SkyColorManager : MonoBehaviour {

	private Color skyColor;
	private Material fogMat;
	
	public Gradient gradient;

	public GameObject boxSprite;

	private float timeCounter = 0;
	void Start()
	{
		fogMat = boxSprite.GetComponent<Renderer>().sharedMaterial;
	}
	
	void Update ()
	{
		// timeCounter += Time.deltaTime*0.1f;
		timeCounter += Time.deltaTime*0.5f;
		Camera.main.backgroundColor = gradient.Evaluate(Mathf.PingPong(timeCounter, 1));
		fogMat.SetColor("_SkyColor", Camera.main.backgroundColor);
	}
}

最后给这些Sprite添加一些上下移动效果,创建SpriteAnim.cs , 并讲他挂到创建的Sprite 上。

public class SpriteAnim : MonoBehaviour
{
	private float maxPosY;

	private Vector3 mInitPos;

	private float mTimeCounter = 0;
	// Use this for initialization
	void Start ()
	{
		mInitPos = this.transform.position;
		
		maxPosY = Random.Range(1, 2.0f);
		
	}
	
	// Update is called once per frame
	void Update ()
	{
		// mTimeCounter += Time.deltaTime * 0.5f;
		mTimeCounter += Time.deltaTime * 1.0f;
		this.transform.position = mInitPos + Vector3.up * (Mathf.PingPong(mTimeCounter,maxPosY)-maxPosY/2.0f);

	}
}

最终效果如下。

Kapture 2019-07-17 at 22.13.13.gif

Unity完整工程源码:请搜索微信公众号UnityAsk,或者 加QQ群:891920228 获取

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值