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.