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
}
}
}
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.
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
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.
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.
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
@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?
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 :)?