Pixel color replacement shader.

How can I write a shader to test the value of a pixel and if is a certain color then replace it with the color of the pixel of another camera in the same screen position?

I imagine there are 2 approaches:

1 - don’t draw the pixel, leaving the camera’s clear flags to “depth only”, making the engine replace the non-drawn pixels with the pixels of the other camera with a lower depth;

2 - replace the pixels with pixels of another texture.

I tried the second approach, adapting a shader I found, resulting in this:

Shader "ColorReplacement" {

    Properties {

        _MainTex ("Greyscale (R) Alpha (A)", 2D) = "white" {}

        _ColorRamp ("Colour Palette", 2D) = "gray" {}

    }
    SubShader {
    	ZTest LEqual
    	ZWrite On
        Pass {
            Name "ColorReplacement"
            CGPROGRAM
                #pragma vertex vert
                #pragma fragment frag
                #pragma fragmentoption ARB_precision_hint_fastest
                #include "UnityCG.cginc"

                struct v2f
                {
                    float4  pos : SV_POSITION;
                    float2  uv : TEXCOORD0;
                }; 

                v2f vert (appdata_tan v)
                {
                    v2f o;
                    o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
                    o.uv = v.texcoord.xy;
                    return o;
                }
                
                sampler2D _MainTex;
                sampler2D _ColorRamp;

                float4 frag(v2f i) : COLOR
                {
                // SURFACE COLOUR
                    float greyscale = tex2D(_MainTex, i.uv).r;
                // RESULT
                    float4 result;
                    result = tex2D(_MainTex, i.uv);
                    if(result.a > 0.5)
                    	result.rgb = tex2D(_MainTex, i.uv).rgb;
                    else
                    	result.rgb = tex2D(_ColorRamp, i.uv).rgb;
                    return result;
                }
            ENDCG
        }
    }
    Fallback off
 }

It works but, replacing to whatever is in the _ColorRamp texture when the pixel alpha is greater than 0.5. But the problem is that it considers the rotation and scale, as if the replacement texture was applied to the GameObject, which I don’t want.

To exemplify, some figures. Here is a square smile figure using a regular unlit shader (no transparency). The part in white has transparency, the checkered background is drawn by a second camera with a lower depth:

[24759-screen+shot+2014-04-05+at+9.21.51+pm.png|24759]

This is what I get using the above shader on the left, and the desired result on the right:

[24761-screen+shot+2014-04-05+at+10.06.24+pm.png|24761]

The desired result was achieve using a regular unlit transparent shader. However, I cannot use this shader because I don’t want transparency, that is, if there’s something behind the smiley game object, it shouldn’t be visible.

@roberto_sc I have a same problem and I found the solution which is “Depth Mask”!

http://wiki.unity3d.com/index.php?title=DepthMask

I use this one. It works.

Shader "Depth Mask Complex"
{
    SubShader
    {
        Tags {"Queue" = "Background"}
        Blend SrcAlpha OneMinusSrcAlpha
        Lighting Off
        ZWrite On
        ZTest Always
        Pass
        {
            Color(0,0,0,0)
        }
    }
}

If all you’re looking for is to remove the white space from around or inside an image, edit the image in a simple editor, erase all the white that you do not want, and save the image as a .png. Unity will take care of the rest.