I quite understand how projective texturing works. I implemented successfully a shader for that following nvidia doc.
The major problem I'm facing is that with that implementation the projector frustum is used only to determine the texture coordinate in projective space, but it doesn't clip anything outside the projective frustum volume.
In other words, if I have a projector pointing toward a object, the texture will be projected on it even if the object is outside its frustum. In addition when projector is almost parallell to the projected object, the texture stretching is too evident and I would like to fade it out.
Now, I'm trying to understand how Unity
handles their built-in projectors. I found this example.
Here's vertex and fragment relevant code:
v2f vert (float4 vertex : POSITION)
{
v2f o;
o.pos = mul (UNITY_MATRIX_MVP, vertex);
o.uvShadow = mul (_Projector, vertex);
o.uvFalloff = mul (_ProjectorClip, vertex);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
fixed4 texS = tex2Dproj (_ShadowTex, UNITY_PROJ_COORD(i.uvShadow));
texS.rgb *= _Color.rgb;
texS.a = 1.0-texS.a;
fixed4 texF = tex2Dproj (_FalloffTex, UNITY_PROJ_COORD(i.uvFalloff));
fixed4 res = texS * texF.a;
return res;
}
I think that _Projector
matrix is a classical matrix to transform vertices coordinates into projector space. (In fact the fragment just use the transformed coordinates to sample the projected texture).
What I'm really missing is how Unity construct _ProjectionClip
matrix. The transformed vertex coordinates are used to sample the falloff texture (that I think it is what I really need).
Does anyone know how the _ProjectionClip
is constructed? Or how to achieve a similar effect?
Note: I did something similar for calculating spotlights falloff, but there I used a single matrix multiplication in the vertex shader to transform vertices into lightspace, and the squared distance in the fragment shader to calculate texture coords for a lookup into the attenuation texture.