Unity Grayscale Shader for Sprite Overlays & More!

This Unity grayscale shader allows everything behind an object mask be rendered in grayscale.

Set the material of a Unity Canvas sprite renderer or NGUI UITexture to this shader and everything with a lower depth index will be rendered in grayscale (black and white).

Grayscale shader example with a square sprite on NGUI (Next Generation UI)


Try the grayscale shader yourself!

Save the shader below and if you’re using Unity Canvas add a custom material using the shader to your sprite renderer. If you’re using NGUI create a UI Texture as the overlay texture and set the shader to the grayscale shader.

Make sure the depth layer of the grayscale texture is higher than the other textures you’re wanting to be affected. If you want certain objects to ignore the grayscale effect too you can just render them in front of the mask overlay.

Shader "Unity3dTips/GrayscaleTransparent" {
	Properties {
		_MainTex ("Texture", 2D) = "white" {}
		_Color("Color", Color) = (1,1,1,1)
	}
	SubShader {
		GrabPass { "_BackgroundTexture" }
	
		Pass {
			Tags { "Queue" = "Transparent" "RenderType" = "Transparent" }

			ZWrite Off
			ZTest Off

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

			sampler2D _BackgroundTexture;
			sampler2D _MainTex;
			fixed4 _MainTex_ST;

			struct v2f {
				fixed4 vertex : SV_POSITION;
				fixed4 grabUV : TEXCOORD1;
			};

			struct appdata {
				fixed4 vertex : POSITION;
			};

			v2f vert (appdata v) {
				v2f o;
				o.vertex = UnityObjectToClipPos(v.vertex);
				o.grabUV = ComputeGrabScreenPos(o.vertex);
				return o;
			}

			fixed4 frag(v2f i) : SV_Target {
				fixed4 bgc = tex2Dproj(_BackgroundTexture, i.grabUV);

				return (bgc.r + bgc.g + bgc.b) / 3;
			}
			ENDCG
		}
	}

	FallBack Off
}


How the Unity grayscale shader works

The shader uses a grabpass which reads the render of the screen prior to this active shader render then calculates the coordinates of the mask sprite so only the area which the mask covers is rendered, simulating transparency.

The RGB colour data from the pixels is averaged with red plus green plus blue then divided by 3 to get the wanted colour of the gray pixel.

Leave a Reply

Your email address will not be published.