Hey Guys,
I am new to shading but somehow managed to acomplish this for the new 2D Sprite system of Unity.
You can use sliders to control the grayscalevalue
If someone needs grayscale for his textures there you go:
Shader "Sprites/GrayScale"
{
Properties
{
[PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
_Color ("Tint", Color) = (1,1,1,1)
[MaterialToggle] PixelSnap ("Pixel snap", Float) = 0
_EffectAmount ("Effect Amount", Range (0, 1)) = 1.0
}
SubShader
{
Tags
{
"Queue"="Transparent"
"IgnoreProjector"="True"
"RenderType"="Transparent"
"PreviewType"="Plane"
"CanUseSpriteAtlas"="True"
}
Cull Off
Lighting Off
ZWrite Off
Fog { Mode Off }
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;
};
fixed4 _Color;
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;
uniform float _EffectAmount;
fixed4 frag(v2f IN) : COLOR
{
half4 texcol = tex2D (_MainTex, IN.texcoord);
texcol.rgb = lerp(texcol.rgb, dot(texcol.rgb, float3(0.3, 0.59, 0.11)), _EffectAmount);
texcol = texcol * IN.color;
return texcol;
}
ENDCG
}
}
Fallback "Sprites/Default"
}
If you want to change things threw code use this:
_GAMEOBJECT_.renderer.material.SetFloat("_EffectAmount", 0.5f);
Cheers
21 Likes
##EDIT ##
fixed it with:
texcol = texcol * IN.color;
1 Like
This is great! I’m wondering though if it’s possible to modify the code so that parts of the original color gets permanently revealed based on a circle around some coordinates? Similar to how a fog of war shader would work, I would imagine?
Similar to this: http://codepen.io/cwolves/pen/prvnb
1 Like
Thanks a lot Dev6_RC, I was using a shader that was working well on unity editor, but on android the shader was broken, I don’t know why, but the yours worked really good! Thank you a lot!
1 Like
kUr4m4
November 2, 2014, 12:18pm
6
This is really awesome! But I would like to have the same shader effect on regular textures but I’m really bad at shaders…anyone have any clue?
This is very cool and works great, but it doesn’t seem to work with masking in the UI. I applied a material with this shader to a sprite on my canvas with a mask on top of it … and the grayscale texture doesnt get masked. If I change material to none it masks just fine. Is this something that can be added?
azmundai:
This is very cool and works great, but it doesn’t seem to work with masking in the UI. I applied a material with this shader to a sprite on my canvas with a mask on top of it … and the grayscale texture doesnt get masked. If I change material to none it masks just fine. Is this something that can be added?
I am sorry, but I have no time ATM. If i had to guess: this shader is based on the Unity sprites shader ( with some modifications ) You could try to look into the base shader of the unity UI system and add the required features into this one. If you do so feel free to post it here! Help the Community!
That helped me a lot~ Thank you!
vinipc
January 11, 2016, 8:49pm
11
Thanks, this was really helpful.
However, as noted by azmundai, it doesn’t work with Unity UI’s Image, so I used your shader to modify Unity’s default shader and came up with this:
Shader "Grayscale"
{
Properties
{
[PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
_Color ("Tint", Color) = (1,1,1,1)
_StencilComp ("Stencil Comparison", Float) = 8
_Stencil ("Stencil ID", Float) = 0
_StencilOp ("Stencil Operation", Float) = 0
_StencilWriteMask ("Stencil Write Mask", Float) = 255
_StencilReadMask ("Stencil Read Mask", Float) = 255
_ColorMask ("Color Mask", Float) = 15
_GrayscaleAmount ("Grayscale Amount", Range (0, 1)) = 1.0
[Toggle(UNITY_UI_ALPHACLIP)] _UseUIAlphaClip ("Use Alpha Clip", Float) = 0
}
SubShader
{
Tags
{
"Queue"="Transparent"
"IgnoreProjector"="True"
"RenderType"="Transparent"
"PreviewType"="Plane"
"CanUseSpriteAtlas"="True"
}
Stencil
{
Ref [_Stencil]
Comp [_StencilComp]
Pass [_StencilOp]
ReadMask [_StencilReadMask]
WriteMask [_StencilWriteMask]
}
Cull Off
Lighting Off
ZWrite Off
ZTest [unity_GUIZTestMode]
Blend SrcAlpha OneMinusSrcAlpha
ColorMask [_ColorMask]
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#include "UnityUI.cginc"
#pragma multi_compile __ UNITY_UI_ALPHACLIP
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 worldPosition : TEXCOORD1;
};
fixed4 _Color;
fixed4 _TextureSampleAdd;
float4 _ClipRect;
uniform float _GrayscaleAmount;
v2f vert(appdata_t IN)
{
v2f OUT;
OUT.worldPosition = IN.vertex;
OUT.vertex = mul(UNITY_MATRIX_MVP, OUT.worldPosition);
OUT.texcoord = IN.texcoord;
#ifdef UNITY_HALF_TEXEL_OFFSET
OUT.vertex.xy += (_ScreenParams.zw-1.0)*float2(-1,1);
#endif
OUT.color = IN.color * _Color;
return OUT;
}
sampler2D _MainTex;
fixed4 frag(v2f IN) : SV_Target
{
half4 color = (tex2D(_MainTex, IN.texcoord) + _TextureSampleAdd) * IN.color;
color.a *= UnityGet2DClipping(IN.worldPosition.xy, _ClipRect);
color.rgb = lerp(color.rgb, dot(color.rgb, float3(0.3, 0.59, 0.11)), _GrayscaleAmount);
#ifdef UNITY_UI_ALPHACLIP
clip (color.a - 0.001);
#endif
return color;
}
ENDCG
}
}
}
Hope it helps!
2459409–169118–UI-Grayscale.shader (2.3 KB)
15 Likes
Thanks you it’s Great !. Work on Android, tested !
vinipc:
Thanks, this was really helpful.
However, as noted by azmundai, it doesn’t work with Unity UI’s Image, so I used your shader to modify Unity’s default shader and came up with this:
Shader "Grayscale"
{
Properties
{
[PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
_Color ("Tint", Color) = (1,1,1,1)
_StencilComp ("Stencil Comparison", Float) = 8
_Stencil ("Stencil ID", Float) = 0
_StencilOp ("Stencil Operation", Float) = 0
_StencilWriteMask ("Stencil Write Mask", Float) = 255
_StencilReadMask ("Stencil Read Mask", Float) = 255
_ColorMask ("Color Mask", Float) = 15
_GrayscaleAmount ("Grayscale Amount", Range (0, 1)) = 1.0
[Toggle(UNITY_UI_ALPHACLIP)] _UseUIAlphaClip ("Use Alpha Clip", Float) = 0
}
SubShader
{
Tags
{
"Queue"="Transparent"
"IgnoreProjector"="True"
"RenderType"="Transparent"
"PreviewType"="Plane"
"CanUseSpriteAtlas"="True"
}
Stencil
{
Ref [_Stencil]
Comp [_StencilComp]
Pass [_StencilOp]
ReadMask [_StencilReadMask]
WriteMask [_StencilWriteMask]
}
Cull Off
Lighting Off
ZWrite Off
ZTest [unity_GUIZTestMode]
Blend SrcAlpha OneMinusSrcAlpha
ColorMask [_ColorMask]
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#include "UnityUI.cginc"
#pragma multi_compile __ UNITY_UI_ALPHACLIP
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 worldPosition : TEXCOORD1;
};
fixed4 _Color;
fixed4 _TextureSampleAdd;
float4 _ClipRect;
uniform float _GrayscaleAmount;
v2f vert(appdata_t IN)
{
v2f OUT;
OUT.worldPosition = IN.vertex;
OUT.vertex = mul(UNITY_MATRIX_MVP, OUT.worldPosition);
OUT.texcoord = IN.texcoord;
#ifdef UNITY_HALF_TEXEL_OFFSET
OUT.vertex.xy += (_ScreenParams.zw-1.0)*float2(-1,1);
#endif
OUT.color = IN.color * _Color;
return OUT;
}
sampler2D _MainTex;
fixed4 frag(v2f IN) : SV_Target
{
half4 color = (tex2D(_MainTex, IN.texcoord) + _TextureSampleAdd) * IN.color;
color.a *= UnityGet2DClipping(IN.worldPosition.xy, _ClipRect);
color.rgb = lerp(color.rgb, dot(color.rgb, float3(0.3, 0.59, 0.11)), _GrayscaleAmount);
#ifdef UNITY_UI_ALPHACLIP
clip (color.a - 0.001);
#endif
return color;
}
ENDCG
}
}
}
Hope it helps!
Nice! Everything that helps improving this shader and unity itself is appriciated!
Waow guys, it’s awesome ! Thank you very much for these two Grey Scale shader scripts.
There are very useful !
Cuisor
June 16, 2016, 12:29pm
15
Thanks, this was really helpfull.
Just what I needed! Thanks @RChrispy !
FUN FACT: I was curious about the magic vector (0.3, 0.59, 0.11) in this line:
color.rgb= lerp(color.rgb, dot(color.rgb, float3(0.3, 0.59, 0.11)), _GrayscaleAmount);
…they’re saying something like “make the grayscale whiteness value of a color 0.3R + 0.59G + 0.11B” but where do those coefficients come from? I looked it up and it seems they come from the NTSC TV standard/the way human eyes work: ~60% of perceived luminosity comes from green, ~30% from red, ~10% from blue.
1 Like
harleywinks:
Just what I needed! Thanks @RChrispy !
FUN FACT: I was curious about the magic vector (0.3, 0.59, 0.11) in this line:
color.rgb= lerp(color.rgb, dot(color.rgb, float3(0.3, 0.59, 0.11)), _GrayscaleAmount);
…they’re saying something like “make the grayscale whiteness value of a color 0.3R + 0.59G + 0.11B” but where do those coefficients come from? I looked it up and it seems they come from the NTSC TV standard/the way human eyes work: ~60% of perceived luminosity comes from green, ~30% from red, ~10% from blue.
Hey harleywinks Thanks for your kind reply!
This happened a long time ago, but if I remember corectly this was the base Vector unity used in it’s Sprite Shader. I used it to modify the color so the “real” Color and the “Grayscaled” Color look best
sfilo
October 11, 2016, 5:26pm
18
I was just beginning to look into grayscale sprites. This made my life a lot easier. Thank you!
dasm30
March 20, 2017, 3:57pm
19
vinipc:
Thanks, this was really helpful.
However, as noted by azmundai, it doesn’t work with Unity UI’s Image, so I used your shader to modify Unity’s default shader and came up with this:
Shader "Grayscale"
{
Properties
{
[PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
_Color ("Tint", Color) = (1,1,1,1)
_StencilComp ("Stencil Comparison", Float) = 8
_Stencil ("Stencil ID", Float) = 0
_StencilOp ("Stencil Operation", Float) = 0
_StencilWriteMask ("Stencil Write Mask", Float) = 255
_StencilReadMask ("Stencil Read Mask", Float) = 255
_ColorMask ("Color Mask", Float) = 15
_GrayscaleAmount ("Grayscale Amount", Range (0, 1)) = 1.0
[Toggle(UNITY_UI_ALPHACLIP)] _UseUIAlphaClip ("Use Alpha Clip", Float) = 0
}
SubShader
{
Tags
{
"Queue"="Transparent"
"IgnoreProjector"="True"
"RenderType"="Transparent"
"PreviewType"="Plane"
"CanUseSpriteAtlas"="True"
}
Stencil
{
Ref [_Stencil]
Comp [_StencilComp]
Pass [_StencilOp]
ReadMask [_StencilReadMask]
WriteMask [_StencilWriteMask]
}
Cull Off
Lighting Off
ZWrite Off
ZTest [unity_GUIZTestMode]
Blend SrcAlpha OneMinusSrcAlpha
ColorMask [_ColorMask]
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#include "UnityUI.cginc"
#pragma multi_compile __ UNITY_UI_ALPHACLIP
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 worldPosition : TEXCOORD1;
};
fixed4 _Color;
fixed4 _TextureSampleAdd;
float4 _ClipRect;
uniform float _GrayscaleAmount;
v2f vert(appdata_t IN)
{
v2f OUT;
OUT.worldPosition = IN.vertex;
OUT.vertex = mul(UNITY_MATRIX_MVP, OUT.worldPosition);
OUT.texcoord = IN.texcoord;
#ifdef UNITY_HALF_TEXEL_OFFSET
OUT.vertex.xy += (_ScreenParams.zw-1.0)*float2(-1,1);
#endif
OUT.color = IN.color * _Color;
return OUT;
}
sampler2D _MainTex;
fixed4 frag(v2f IN) : SV_Target
{
half4 color = (tex2D(_MainTex, IN.texcoord) + _TextureSampleAdd) * IN.color;
color.a *= UnityGet2DClipping(IN.worldPosition.xy, _ClipRect);
color.rgb = lerp(color.rgb, dot(color.rgb, float3(0.3, 0.59, 0.11)), _GrayscaleAmount);
#ifdef UNITY_UI_ALPHACLIP
clip (color.a - 0.001);
#endif
return color;
}
ENDCG
}
}
}
Hope it helps!
Helloo, so no warnings, but GrayscaleAmount is not working, the image/sprite always looks gray.
I made a Sprite/Diffuse version from the builtin shader & the grayscale version:
// Unity built-in shader source. Copyright (c) 2016 Unity Technologies. MIT license (see license.txt)
Shader "Sprites/GrayScale"
{
Properties
{
[PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
_Color ("Tint", Color) = (1,1,1,1)
[MaterialToggle] PixelSnap ("Pixel snap", Float) = 0
[HideInInspector] _RendererColor ("RendererColor", Color) = (1,1,1,1)
[HideInInspector] _Flip ("Flip", Vector) = (1,1,1,1)
[PerRendererData] _AlphaTex ("External Alpha", 2D) = "white" {}
[PerRendererData] _EnableExternalAlpha ("Enable External Alpha", Float) = 0
_EffectAmount ("Effect Amount", Range (0, 1)) = 1.0
}
SubShader
{
Tags
{
"Queue"="Transparent"
"IgnoreProjector"="True"
"RenderType"="Transparent"
"PreviewType"="Plane"
"CanUseSpriteAtlas"="True"
}
Cull Off
Lighting Off
ZWrite Off
Blend One OneMinusSrcAlpha
CGPROGRAM
#pragma surface surf Lambert vertex:vert nofog nolightmap nodynlightmap keepalpha noinstancing
#pragma multi_compile _ PIXELSNAP_ON
#pragma multi_compile _ ETC1_EXTERNAL_ALPHA
#include "UnitySprites.cginc"
struct Input
{
float2 uv_MainTex;
fixed4 color;
};
void vert (inout appdata_full v, out Input o)
{
v.vertex.xy *= _Flip.xy;
#if defined(PIXELSNAP_ON)
v.vertex = UnityPixelSnap (v.vertex);
#endif
UNITY_INITIALIZE_OUTPUT(Input, o);
o.color = v.color * _Color * _RendererColor;
}
uniform float _EffectAmount;
void surf (Input IN, inout SurfaceOutput o)
{
fixed4 c = SampleSpriteTexture (IN.uv_MainTex) * IN.color;
c.rgb = lerp(c.rgb, dot(c.rgb, float3(0.3, 0.59, 0.11)), _EffectAmount);
o.Albedo = c.rgb * c.a;
o.Alpha = c.a;
}
ENDCG
}
Fallback "Sprite/Diffuse"
}
2 Likes