Unity Projector可以模拟投影机效果,但是在投影画面边缘透明度不是0的情况下经常出现拉伸现象,对投影机的shader做如下更改可以去除掉拉伸部分。
Unity自带的投影shader:
// Upgrade NOTE: replaced '_Projector' with 'unity_Projector'
// Upgrade NOTE: replaced '_ProjectorClip' with 'unity_ProjectorClip'Shader "Projector/Multiply" {Properties {_ShadowTex ("Cookie", 2D) = "gray" {}_FalloffTex ("FallOff", 2D) = "white" {}}Subshader {Tags {"Queue"="Transparent"}Pass {ZWrite OffColorMask RGBBlend DstColor ZeroOffset -1, -1CGPROGRAM#pragma vertex vert#pragma fragment frag#pragma multi_compile_fog#include "UnityCG.cginc"struct v2f {float4 uvShadow : TEXCOORD0;float4 uvFalloff : TEXCOORD1;UNITY_FOG_COORDS(2)float4 pos : SV_POSITION;};float4x4 unity_Projector;float4x4 unity_ProjectorClip;v2f vert (float4 vertex : POSITION){v2f o;o.pos = UnityObjectToClipPos(vertex);o.uvShadow = mul (unity_Projector, vertex);o.uvFalloff = mul (unity_ProjectorClip, vertex);UNITY_TRANSFER_FOG(o,o.pos);return o;}sampler2D _ShadowTex;sampler2D _FalloffTex;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 = lerp(fixed4(1,1,1,0), texS, texF.a);UNITY_APPLY_FOG_COLOR(i.fogCoord, res, fixed4(1,1,1,1));return res;}ENDCG}}
}
去除边缘拉伸之后:
// Upgrade NOTE: replaced '_Projector' with 'unity_Projector'
// Upgrade NOTE: replaced '_ProjectorClip' with 'unity_ProjectorClip'Shader "Projector/Multiply" {Properties {_ShadowTex ("Cookie", 2D) = "gray" {}_FalloffTex ("FallOff", 2D) = "white" {}}Subshader {Tags {"Queue"="Transparent"}Pass {ZWrite OffColorMask RGBBlend DstColor ZeroOffset -1, -1CGPROGRAM#pragma vertex vert#pragma fragment frag#pragma multi_compile_fog#include "UnityCG.cginc"struct v2f {float4 uvShadow : TEXCOORD0;float4 uvFalloff : TEXCOORD1;UNITY_FOG_COORDS(2)float4 pos : SV_POSITION;};float4x4 unity_Projector;float4x4 unity_ProjectorClip;v2f vert (float4 vertex : POSITION){v2f o;o.pos = UnityObjectToClipPos(vertex);o.uvShadow = mul (unity_Projector, vertex);o.uvFalloff = mul (unity_ProjectorClip, vertex);UNITY_TRANSFER_FOG(o,o.pos);return o;}sampler2D _ShadowTex;sampler2D _FalloffTex;fixed4 frag (v2f i) : SV_Target{fixed4 texS;//去除边缘及背面if (i.uvShadow.x / i.uvShadow.w < 0.01 || i.uvShadow.x / i.uvShadow.w > 0.99 || i.uvShadow.y / i.uvShadow.w < 0.01 || i.uvShadow.y / i.uvShadow.w > 0.99){texS = float4(0, 0, 0, 0);}else {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 = lerp(fixed4(1,1,1,0), texS, texF.a);UNITY_APPLY_FOG_COLOR(i.fogCoord, res, fixed4(1,1,1,1));return res;}ENDCG}}
}
运行效果: