I’m using the Projector component to paint decals of blood on the environment.
The issue is that the blood gets stretched on the sides of the object it is projected on.

I’m using this shader to paint the texture on the object:
{
Properties
{
_ShadowTex ("Cookie", 2D) = "white" { TexGen ObjectLinear }
}
Subshader
{
Tags { "RenderType"="Transparent" "Queue"="Transparent+100"}
Pass
{
ZWrite Off
Offset -1, -1
Fog { Mode Off }
ColorMask RGB
Blend OneMinusSrcAlpha SrcAlpha
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma fragmentoption ARB_fog_exp2
#pragma fragmentoption ARB_precision_hint_fastest
#include "UnityCG.cginc"
struct v2f
{
float4 pos : SV_POSITION;
float4 uv : TEXCOORD0;
float intensity : TEXCOORD3;
};
sampler2D _ShadowTex;
float4x4 unity_Projector;
float4x4 unity_ProjectorClip;
float4 _Color;
v2f vert(appdata_tan v, float3 normal : NORMAL)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.uv = mul (unity_Projector, v.vertex);
return o;
}
half4 frag (v2f i) : COLOR
{
half4 tex = tex2Dproj(_ShadowTex, i.uv);
tex.a = 1-tex.a;
if (i.uv.w < 0)
{
tex = float4(0,0,0,1);
}
clip(1 + i.uv.z);
clip(1 - i.uv.z);
return tex;
}
ENDCG
}
}
}
How would I limit the shader to only project the texture on the surface of the object directly infront of the projector? Ideally with an angle parameter, so that uniform objects wouldn’t be cut off.
I tried using SetVector to set the forward vector of the projector in runtime
GetComponent<Projector>().material.SetVector("_ProjectorWorldForward", -transform.forward);
and added these lines to the shader:
(..)
uniform float3 _ProjectorWorldForward = float3(0.0, 1.0, 0.0);
(..)
o.intensity = sign(dot(_ProjectorWorldForward, UnityObjectToWorldNormal(normal)));
(..)
tex.a *=i.intensity;
However, that didn’t work either.