Invert Colors Shader

Hey guys, I thought I’d share this simple transparent shader. It inverts the colors of anything behind the mesh to which it is applied. It also has a tint parameter. Also it works for Unity Free.

I’m new to shaders, so if there’s any way to make it more efficient, feel free to tell me!

The .shader file is attached, but here’s the code because sometimes, downloading stuff is annoying:

Shader "ddShaders/dd_Invert" {
Properties 
	{
		_Color ("Tint Color", Color) = (1,1,1,1)
	}
	
	SubShader 
	{
		Tags { "Queue"="Transparent" }

		Pass
		{
		   ZWrite On
		   ColorMask 0
		}
        Blend OneMinusDstColor OneMinusSrcAlpha //invert blending, so long as FG color is 1,1,1,1
        BlendOp Add
        
        Pass
		{ 
		
CGPROGRAM
#pragma vertex vert
#pragma fragment frag 
uniform float4 _Color;

struct vertexInput
{
	float4 vertex: POSITION;
    float4 color : COLOR;	
};

struct fragmentInput
{
	float4 pos : SV_POSITION;
	float4 color : COLOR0; 
};

fragmentInput vert( vertexInput i )
{
	fragmentInput o;
	o.pos = mul(UNITY_MATRIX_MVP, i.vertex);
	o.color = _Color;
	return o;
}

half4 frag( fragmentInput i ) : COLOR
{
	return i.color;
}

ENDCG
}
}
}


1386454–70980–$dd_Invert.shader (776 Bytes)

11 Likes

Hey just wanted to thank you for this as it seems no one else has.
This shader is helping out a lot right now. Cheers!

1 Like

You should adjust the formatting in your embedded example. But that’s just me being picky.

1 Like

I appreciate that, p13t3rm!

Attached is an updated version of the shader that trims off a bunch of unnecessary code, if you are interested (also should address the formatting issue).
Additionally, I’ve attached a version of the shader for use in Linear Color Space.

1460488–79558–$ddInvert.shader (680 Bytes)
1460488–262467–$ddInvertLin.shader (1.21 KB)

2 Likes

cool stuff.

Very cool! I’ve been putting off learning shaders but this is almost exactly what I wanted to make.

In case you ever feel like tinkering with it some more, a request: It’d be fantastic if there was an optional (variable) desaturation stage applied after the inverion, but before the tint was applied. If that was in there I could put off learning shaders for even longer :wink:

I will definitely take that challenge, but there is a strong chance it would only be possible with Pro things such as Grab Pass (I don’t have Unity Pro yet)

Well, after hours of tinkering, I can say a desaturation pass is beyond my abilities. The big problem is that it requires a color channel to read and mix with the other color channels, which is not something Blend does easily.

http://forum.unity3d.com/threads/193930-Transparent-shader-that-makes-objects-behind-it-greyscale

In the above thread, Jessy explains a process, which seems to involve storing the color channels in the alpha, and then using another pass to reveal that alpha. I CAN get a pass to work which reveals the alpha channels, but I cannot get color channels stored in the alpha in the first place.

float3 goGrey = (0.3, 0.59, 0.11);
float3 greyed = dot (color, goGrey);
return fixed4(mix( color, greyed, _desaturation), 1);

Hope it helps, have a nice day.

Hello Community!

I’m wondering how it’s possible to achieve a Shader that inverts an objects color that it touches.

_
the problem with the shader above is, that the object (e.g. an Cube) where the shader is applied to acts like a mirror and inverts everything you look at. I want the object with the shader to be invisible and is just inverting the color of the objects thats inside it.

My Intention is to get a similar result like in the image:

regards
Soulart

Reviving an old thread here, does anyone know if it would be possible to modify this shader to accept a texture rather than just a solid color? As in not the tint color but I’m looking to invert what’s behind based on a black and white texture. So instead of a solid alpha, basically I’d like a texture alpha.

Hi, twbowen. This shader should do the things you need:

Pixels behind the white part of a texture will become inverted, while pixels behind the black part of the texture will keep their original color. It will also tint if your texture image is colorful (in fact this tinting method looks a bit better than the above shaders, IMO)

Make note that, due to the nature of color inversion, a black-white gradient will have a solid-looking gray center.

//ddInvertMapped shader: Daniel DeEntremont
//Apply this shader to a mesh and watch all pixels behind the mesh become inverted!
//Now has a texture mask input. White will invert colors behind while black remains the same.
Shader "ddShaders/ddInvertMapped" {
    Properties
        {
            _Color ("Tint Color", Color) = (1,1,1,1)
            _MainTex("Main Texture", 2D) = "white"{}
        }
   
   
   
        SubShader
        {
            Tags { "Queue"="Transparent" }
     
            Pass
            {
               ZWrite On
               ColorMask 0
            }
        
        
        
            Pass
            {
                Blend OneMinusDstColor OneMinusSrcColor //invert blending, so long as FG color is 1,1,1,1
                BlendOp Add
                SetTexture [_MainTex]
                {
                    constantColor [_Color]
                    combine texture * constant
                }
            }
        
         }//end subshader
}//end shader

2200398–146122–ddInvertMapped.shader (910 Bytes)

5 Likes

Awesome! That’s perfect, thank you so much. I was so close!

This shader is excellent! Thanks so much for sharing it.

Is there any way to make it compatible with render to texture? I can’t figure it out.

@dandeentremont I tried to use the shader in Unity 5.2.2 and it seems like it doesn’t work anymore. Is there anything that needs to change for it to work?

Hi Ben BearFish,

I just downloaded 5.2.2f1 on a macbook and the shaders seem to be running fine here.
What kind of error messages are you getting?

The shader you posted in your first post doesn’t seem to compile, but the later ones you posted seem to work.

Even the first one seems to be working over here. Although the first time I tried, I hadn’t copied the last bracket, so it did fail. Any chance something like that happened :)?

Works for 2D as well. I’ll put you in the credits for now as dandeentremont but I’d like to put you in as your real name. :slight_smile:

It’s close: My real name is Daniel DeEntremont

Thanks so much for your consideration!