shader 2D图片过渡

游戏中背景图片过渡替换,通过透明通道过渡
Shader "2DSprites/transit"
{
	Properties
	{
		_MainTex("Sprite Texture", 2D) = "white" {}
		_MainTex2("Tex2 (RGB)", 2D) = "white" {}
		_MainTex3("Tex3 (RGB)", 2D) = "white" {}
		_Color("Tint", Color) = (1,1,1,1)
		[MaterialToggle] PixelSnap("Pixel snap", Float) = 0
		_Glossiness("Smoothness", Range(0,1)) = 0.5
		// Add values to determine if outlining is enabled and outline color.
		[PerRendererData] _Outline("Outline", Float) = 0
		[PerRendererData] _OutlineColor("Outline Color", Color) = (1,1,1,1)
	}

		SubShader
	{
		Tags
	{
		"Queue" = "Transparent"
		"IgnoreProjector" = "True"
		"RenderType" = "Transparent"
		"PreviewType" = "Plane"
		"CanUseSpriteAtlas" = "True"
	}

		Cull Off
		Lighting Off
		ZWrite Off
		Blend One OneMinusSrcAlpha

		Pass
	{
		CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile _ PIXELSNAP_ON
#pragma shader_feature ETC1_EXTERNAL_ALPHA
#include "UnityCG.cginc"

		struct appdata_t
	{
		float4 vertex   : POSITION;
		float4 color    : COLOR;
		float2 texcoord : TEXCOORD0;
	};

	struct v2f
	{
		float4 vertex   : SV_POSITION;
		fixed4 color : COLOR;
		float2 texcoord  : TEXCOORD0;
	};

	fixed4 _Color;
	float _Outline;
	float PixelSnap;
	float _Glossiness;
	fixed4 _OutlineColor;

	v2f vert(appdata_t IN)
	{
		v2f OUT;
		OUT.vertex = mul(UNITY_MATRIX_MVP, IN.vertex);
		OUT.texcoord = IN.texcoord;
		OUT.color = IN.color * _Color;
#ifdef PIXELSNAP_ON
		OUT.vertex = UnityPixelSnap(OUT.vertex);
#endif

		return OUT;
	}

	sampler2D _MainTex;
	sampler2D _MainTex2;
	sampler2D _MainTex3;
	sampler2D _AlphaTex;
	float4 _MainTex_TexelSize;

	fixed4 SampleSpriteTexture(float2 uv)
	{
		fixed4 color = tex2D(_MainTex, uv);
		fixed4 color2 = tex2D(_MainTex2, uv);
		fixed4 color3 = tex2D(_MainTex3, uv);

#if ETC1_EXTERNAL_ALPHA
		// get the color from an external texture (usecase: Alpha support for ETC1 on android)
		//color.a = tex2D(_AlphaTex, uv).r;
#endif //ETC1_EXTERNAL_ALPHA
		if (_Glossiness > color3.a)
		{
			return color;
		}
		return color2;
	}

	fixed4 frag(v2f IN) : SV_Target
	{
		fixed4 c = SampleSpriteTexture(IN.texcoord) * IN.color;

	// If outline is enabled and there is a pixel, try to draw an outline.
	if (PixelSnap > 0 && c.a != 0) {
		// Get the neighbouring four pixels.
		fixed4 pixelUp = tex2D(_MainTex, IN.texcoord + fixed2(_Outline, _MainTex_TexelSize.y));
		fixed4 pixelDown = tex2D(_MainTex, IN.texcoord - fixed2(_Outline, _MainTex_TexelSize.y));
		fixed4 pixelRight = tex2D(_MainTex, IN.texcoord + fixed2(_MainTex_TexelSize.x, _Outline));
		fixed4 pixelLeft = tex2D(_MainTex, IN.texcoord - fixed2(_MainTex_TexelSize.x, _Outline));

		// If one of the neighbouring pixels is invisible, we render an outline.
		if (pixelUp.a * pixelDown.a * pixelRight.a * pixelLeft.a == 0) {
			c.rgba = fixed4(1, 1, 1, 1) * _OutlineColor;
		}
	}

	c.rgb *= c.a;

	return c;
	}
		ENDCG
	}
	}
}

### 实现 Unity 场景过渡效果的 ShaderUnity 中,场景过渡效果可以通过编写自定义 Shader 来实现。下面是一个基于时间流逝模拟时钟指针扫过一圈并伴随图像逐渐消失和显现的效果。 #### 创建 Shader 文件 按照描述的方法创建新的 Shader 文件[^1]: ```csharp // 在 Unity 编辑器中选择 Assets -> Create -> Shader 或者右键点击项目视图中的空白处 -> Create -> Shader。 ``` #### 定义表面着色器结构 对于这种特定类型的过渡效果,可以采用 `Surface Shader` 结构,并利用纹理坐标计算角度变化来控制显示区域[^2]。 ```cpp Shader "Custom/WipeTransition" { Properties { _MainTex ("Texture", 2D) = "white" {} _Progress ("Progress (0 to 1)", Range(0,1)) = 0.5 _EdgeWidth ("Edge Width", Float) = 0.1 } SubShader { Tags { "RenderType"="Opaque" } CGPROGRAM #pragma surface surf Lambert vertex:vert addshadow fullforwardshadows sampler2D _MainTex; float _Progress; float _EdgeWidth; struct Input { float2 uv_MainTex; }; void vert(inout appdata_full v, out Input data){ UNITY_INITIALIZE_OUTPUT(Input,data); // 计算当前顶点相对于中心的角度 float angle = atan2(v.vertex.y,v.vertex.x)+UNITY_PI; angle /= UNITY_TWO_PI; // 将进度映射到圆形路径上 float progressAngle = lerp(-_EdgeWidth/2,_EdgeWidth/2,fmod(_Progress*UNITY_TWO_PI,UNITY_TWO_PI)); if(angle<_Progress-progressAngle || angle>_Progress+progressAngle){ v.color.a=lerp(0,1,saturate((abs(angle-_Progress)-_EdgeWidth)/fwidth(progressAngle))); }else{ v.color.a=1; } } void surf (Input IN, inout SurfaceOutput o) { fixed4 col = tex2D (_MainTex, IN.uv_MainTex)*IN.color; o.Albedo = col.rgb; o.Alpha = col.a; } ENDCG } } ``` 此代码片段实现了如下功能: - 使用 `_Progress` 属性调整过渡过程的位置; - 利用 `_EdgeWidth` 控制过渡边界的宽度和平滑度; - 借助 `atan2()` 函数根据顶点位置计算其对应的角度值; - 应用了线性插值算法 (`lerp()`) 和平滑步长函数 (`saturate()`) 来生成柔和的边界效果; #### 设置材质球应用 Shader 完成上述 Shader 后,需将其应用于实际的游戏对象或 UI 组件之上。这通常涉及到创建一个 Material 并指定刚才编写的 Shader,再将这个 Material 分配给目标物体。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值