- Home /
Why does not perspective projectors work well?
With Unity 5.2.1f1, I'm trying to use a Projector
to project an image to a given mesh. I have a simple scene that contains a camera, a directional light source, a plane as the mesh to project things on and a fourth GameObject
that has a Projector
component.
When I set the Projector
to be orthographic, it works pretty good.
But I hope to use it as a mock light source that works on a baked scene, so I wish it to work well when perspective. Now the problem shows up.
My shader on the plane is simply Legacy Shaders/Diffuse
, and the shader used for the projector is as follows.
Shader "Cg projector shader for adding light"
{
Properties
{
_ShadowTex("Projected Image", 2D) = "white" {}
_AlphaFactor("Alpha Factor", Range(0.0, 3.0)) = 1.0
_MainColor("Color", Color) = (1, 1, 1, 0)
}
SubShader
{
Pass
{
Blend SrcAlpha OneMinusSrcAlpha
ZWrite Off
Offset -1, -1
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
uniform sampler2D _ShadowTex;
uniform fixed _AlphaFactor;
uniform fixed4 _MainColor;
// Projector-specific uniforms
uniform float4x4 _Projector; // transformation matrix from object space to projector space
struct vertexInput
{
float4 vertex : POSITION;
float3 normal : NORMAL;
};
struct vertexOutput
{
float4 pos : SV_POSITION;
float4 posProj : TEXCOORD0; // position in projector space
};
vertexOutput vert(vertexInput input)
{
vertexOutput output;
output.posProj = mul(_Projector, input.vertex);
output.pos = mul(UNITY_MATRIX_MVP, input.vertex);
return output;
}
fixed4 frag(vertexOutput input) : COLOR
{
// In front of projector and within the boundary of the texture.
if (input.posProj.w > 0.0 && input.posProj.x <= 1.0 && input.posProj.y <= 1.0 && input.posProj.x >= 0.0 && input.posProj.y >= 0.0)
{
fixed4 retColor = tex2Dproj(_ShadowTex, input.posProj) * _MainColor;
retColor.a = clamp(retColor.a * _AlphaFactor, 0.0, 1.0);
return retColor;
}
return fixed4(0.0, 0.0, 0.0, 0.0);
}
ENDCG
}
}
Fallback "Mobile/Diffuse"
}
This shader comes from the internet, and the main change I made is adding x
and y
restrictions to the if
statement in the fragment function, because I don't want the clamp or repeated effects of the projected image is shown anywhere outside the frustrum. So is there anything I can do with matrices and apply them to the boundary of the if
statement? Or, am I totally doing wrong?
Thanks.