Unity Texture置灰处理

最近搞了一下置灰相关内容,这个鬼东西...真是坑

如果用的地方不多的话,那就让美术出图吧...不过如果各个地方都在用,我们还是老老实实写个shader吧,不然还是很浪费资源的..

我用的NGUI,其实这个关系不是很大啦..NGUI里有一个Transparent Colored shader,这个如果你创建NGUI Texture会默认用这个shader。

我们的做法也很简单,就是如果Texutre的color tint 的rgb设置为(0,0,0)的时候,我们就让其置灰

Shader代码如下

Shader "Unlit/Transparent Colored"
{
	Properties
	{
		_MainTex ("Base (RGB), Alpha (A)", 2D) = "black" {}
	}
	
	SubShader
	{
		LOD 200

		Tags
		{
			"Queue" = "Transparent"
			"IgnoreProjector" = "True"
			"RenderType" = "Transparent"
			"DisableBatching" = "True"
		}
		
		Pass
		{
			Cull Off
			Lighting Off
			ZWrite Off
			Fog { Mode Off }
			Offset -1, -1
			Blend SrcAlpha OneMinusSrcAlpha

			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag			
			#include "UnityCG.cginc"

			sampler2D _MainTex;
			float4 _MainTex_ST;
			fixed4 _Color;
	
			struct appdata_t
			{
				float4 vertex : POSITION;
				float2 texcoord : TEXCOORD0;
				fixed4 color : COLOR;
				UNITY_VERTEX_INPUT_INSTANCE_ID
			};
	
			struct v2f
			{
				float4 vertex : SV_POSITION;
				half2 texcoord : TEXCOORD0;
				fixed4 color : COLOR;
				UNITY_VERTEX_OUTPUT_STEREO
			};
	
			v2f o;

			v2f vert (appdata_t v)
			{
				UNITY_SETUP_INSTANCE_ID(v);
				UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
				o.vertex = UnityObjectToClipPos(v.vertex);
				o.texcoord = v.texcoord;
				o.color = v.color;
				return o;
			}
				
			fixed4 frag (v2f IN) : SV_Target
			{
				fixed4 texColor = tex2D(_MainTex, IN.texcoord);
				fixed4 col = texColor * IN.color;

				if(IN.color.r + IN.color.g + IN.color.b < 0.0001){
					fixed gray = dot(half3(0.6,0.2,0.01),texColor);
					fixed3 grayCol = fixed3(gray,gray,gray);
					col.rgb = grayCol;
				}
				return col;
			}
			ENDCG
		}
	}

	SubShader
	{
		LOD 100

		Tags
		{
			"Queue" = "Transparent"
			"IgnoreProjector" = "True"
			"RenderType" = "Transparent"
			"DisableBatching" = "True"
		}
		
		Pass
		{
			Cull Off
			Lighting Off
			ZWrite Off
			Fog { Mode Off }
			Offset -1, -1
			//ColorMask RGB
			Blend SrcAlpha OneMinusSrcAlpha
			ColorMaterial AmbientAndDiffuse
			
			SetTexture [_MainTex]
			{
				Combine Texture * Primary
			}
		}
	}
}

这么一大坨代码...懒得看,稍微有点Shader基础的人应该也都知道,多数都是乱七八糟的定义,比如appdata_t,unityshader内置的,v2f shader中常用的顶点到片元等等

直接看fixed4 frag(v2f IN) : SV_Target吧,这个是最终会显示的效果

if(IN.color.r + IN.color.g + IN.color.b < 0.0001){
    fixed gray = dot(half3(0.6,0.2,0.01),texColor);
    fixed3 grayCol = fixed3(gray,gray,gray);
    col.rgb = grayCol;
}

这个v2f IN,IN.color其实也就是Color Tint的rgba值,刚开始我以为需要在Properties中设置一个参数来着,愚钝了

需要注意的是,在Unity中如果说你对UISprite置灰,那么会导致UISprite的Atlas里所有的Texture都会置灰,为什么?

obj:getComponent<UISprite>().material:setColor("_Color", Color.grey)

其实观察UISprite代码知道

public override Material material
	{
		get
		{
			var mat = base.material;
			if (mat != null) return mat;
			return (mAtlas != null ? mAtlas.spriteMaterial : null);
		}
		set
		{
			base.material = value;
		}
	}

通过UISprite取出来的material,其实就是Atlas里的,然而如果你对shader进行更改,或者设置,那么整个Atlas可想而知...

猜你喜欢

转载自blog.csdn.net/zphshiwo/article/details/81666299