What is the code for the shader you are using for the projector? This is actually not very hard to accomplish in shader code. If you could post the code of the shader, I could help you more exactly, but…
What you want to do is add a check to see how “vertical” a surface is, and not alter the color if it is too vertical. Here is some psuedo shader code to demonstrate this:
// assuming Y is up
half3 up = half3(0,1,0);
if(dot(normal, up) == 1) {
// this is a flat floor surface, adjust color
}
That is just a general idea. Odds are it will never be exactly 1 (or might be 0, I forget what the value of a dot product of two matching directions is), so you will need to test for a range.
General idea though is to run a test on the dot product of the normal of the vertex against the world up normal.
EDIT:
I see. ok, first we need to get the normal data:
make a new struct:
struct appdata {
float4 vertex : POSITION;
float3 normal : NORMAL;
}
modify the existing struct:
struct v2f {
float4 uvShadow : TEXCOORD0;
float4 uvFalloff : TEXCOORD1;
float4 pos : SV_POSITION;
float3 norm : NORMAL;
};
Now to modify our vertex function:
v2f vert (appdata i)
{
v2f o;
o.pos = mul (UNITY_MATRIX_MVP, i.vertex);
o.uvShadow = mul (_Projector, i.vertex);
o.uvFalloff = mul (_ProjectorClip, i.vertex);
o.normal = i.normal;
return o;
}
Now our fragment function should have a normal to work with. Now try doing this:
fixed4 frag (v2f i) : SV_Target
{
fixed4 texS = tex2Dproj (_ShadowTex, UNITY_PROJ_COORD(i.uvShadow));
texS.a = 1.0-texS.a;
fixed4 texF = tex2Dproj (_FalloffTex, UNITY_PROJ_COORD(i.uvFalloff));
fixed4 res;
// assume Y is up
if(dot(i.normal, float3(0,1,0)) >= 0.9) {
res = lerp(fixed4(1,1,1,0), texS, texF.a);
} else {
res = texS;
}
return res;
}
For the if statement, you may need to play with that 0.9 value. It is going to be a value between -1 and 1; but I forget what the value will be when the normal and the up vector are the same (or close to it).
This is by no means a complete solution (or maybe it is? I did not test it), but it should help to point you in the right direction. The main points to take are this:
- You need to get normal information to your frag function
- you need to compare the dot product of the normal to the world up vector to figure out how vertical a face is.
I am also unsure what texS and texF contain at this point of the shader. I’m assuming texS is the shaded texture BEFORE the projection is applied, but I could be wrong.
This link should help a bit as well, as it explains inputs to vertex/fragment shaders: