Unity 使用一张贴图来控制材质主贴图的透明度

最近有个需求:通过一张贴图的颜色值来控制材质主贴图的透明度。

先做一个注明:用来控制主贴图透明度的贴图,我们暂且称之为“Alpha贴图”;主贴图就叫“主贴图”。

首先,我们需要解决的是将Alpha贴图的颜色值转化成透明度;经过多方测试,最终采用了以下方法:1)比较像素点的r、g、b;2)假设r最大,则float val = r*权重+g+b;3)alpha = val/(权重+2)

直接上代码:

Shader "Custom/MainTexAlphaCtrl"
{
	Properties
	{
		_MainTex("Texture", 2D) = "white" {}//主贴图纹理
		_AlphaTex("AlphaTexture",2D) = "white"{}//Alpha纹理
		_BaseColor("Base Color",Color) = (1, 1, 1, 1)
		_Weight("Weight",float) = 0//Alpha计算时的权重
		[Toggle(_Reverse)] _Reverse("Reverse", float) = 0//是否取反,用于主贴图的透明度计算
	}
		SubShader
		{
		Tags { "RenderType" = "Transparent"}
			LOD 100
			Cull Off
			//如果使用Alpha混合,需要关闭深度缓冲写入
			ZWrite Off
			//添加混合命令
			Blend SrcAlpha OneMinusSrcAlpha

			Pass
			{
				CGPROGRAM
				#pragma vertex vert
				#pragma fragment frag
				// make fog work
				#pragma multi_compile_fog

				#include "UnityCG.cginc"

				struct appdata
				{
					float4 vertex : POSITION;
					float2 uv : TEXCOORD0;
				};

				struct v2f
				{
					float2 uv : TEXCOORD0;
					float4 vertex : SV_POSITION;
				};

				sampler2D _MainTex;
				sampler2D _AlphaTex;
				float4 _MainTex_ST;
				float4 _BaseColor;
				float _Weight;
				float _Reverse;

				
				v2f vert(appdata v)
				{
					v2f o;
					o.vertex = UnityObjectToClipPos(v.vertex);
					o.uv = TRANSFORM_TEX(v.uv, _MainTex);
					return o;
				}

				//将颜色值转化成透明度
				float color2Alpha(fixed3 col)
				{
					float a = 0;
					float val = 0;
					//比较r、g、b三个值,得到最大值,如果r最大,则val = 4*r+g+b;
					if (col.r > col.g)
					{
						if (col.r > col.b)
						{
							val = _Weight * col.r + col.g + col.b;
						}
						else
						{
							val = _Weight * col.b + col.g + col.r;
						}
					}
					else
					{
						if (col.g > col.b)
						{
							val = _Weight * col.g + col.r + col.b;
						}
						else
						{
							val = _Weight * col.b + col.g + col.r;
						}
					}
					//然后val除以(权重+2),得到最终alpha值
					return val / (_Weight+2);
					//return (col.r + col.g + col.b)/3;
				}

				fixed4 frag(v2f i) : SV_Target
				{
					// sample the texture
					fixed4 main_col = tex2D(_MainTex, i.uv) * _BaseColor;
					fixed3 alpha_col = tex2D(_AlphaTex, i.uv).rgb;
					if (_Reverse == 0)
					{
						return fixed4(main_col.rgb, main_col.a * color2Alpha(alpha_col));
					}
					else
					{
						return fixed4(main_col.rgb, main_col.a * (1 - color2Alpha(alpha_col)));
					}
				}
				ENDCG
			}
		}
}

猜你喜欢

转载自blog.csdn.net/humilezr/article/details/125736925
今日推荐