投影在3D游戏中经常使用,比如弹孔,血溅到地面上,贴花等效果都可以使用投影。
投影在Unity中的是一个Projector的Component,它上面的参数跟Camera的参数极为相似,其实可以理解,它的目的就是为shader提供需要的矩阵参数。最主要的参数就是unity_Projector和unity_ProjectorClip两个。
unity_Projector参数是投影Cookie贴图用,用于计算要投影的图片正确地显示到场景接受投影和模型上。
unity_ProjectorClip参数主要用来处理投影位置和投影器之间的距离,这个参数通常用于Falloff贴图计算上,可以达到离投影器越远影子越淡,越近越清楚。这张falloff图片通常是一张黑白图,左白右黑,注意这张贴图的WrapMode要设置为Clamp,最好关闭mipmap。
下面是投影常见的Shader
Shader "Projector/Multiply"
{
Properties
{
_ShadowTex ("Cookie", 2D) = "gray" { TexGen ObjectLinear }
_FalloffTex ("FallOff", 2D) = "white" { TexGen ObjectLinear }
}
Subshader
{
Tags { "RenderType"="Transparent-1" }
Pass
{
ZWrite Off
Fog { Color (1, 1, 1) }
AlphaTest Less 1
ColorMask RGB
Blend DstColor Zero
Offset -1, -1
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma fragmentoption ARB_precision_hint_fastest
#include "UnityCG.cginc"
struct v2f
{
float4 pos : SV_POSITION;
float4 uv_Main : TEXCOORD0;
float4 uv_Clip : TEXCOORD1;
};
sampler2D _ShadowTex;
sampler2D _FalloffTex;
float4x4 unity_Projector;
float4x4 unity_ProjectorClip;
v2f vert(appdata_tan v)
{
v2f o;
o.pos = UnityObjectToClipPos (v.vertex);
o.uv_Main = mul (unity_Projector, v.vertex);
o.uv_Clip = mul (unity_ProjectorClip, v.vertex);
return o;
}
half4 frag (v2f i) : COLOR
{
half4 tex = tex2Dproj(_ShadowTex, i.uv_Main);
half4 falloff = tex2D(_FalloffTex, i.uv_Clip.xy);
tex = lerp(float4(1,1,1,1),tex,falloff.a);
return tex;
}
ENDCG
}
}
}