策划要求施法范围显示为球形,和地面上的物体相交处高亮,我开始想用Projector投影,但是只能实现柱形,后来想到shader,找到了Kaima_Chen大神的[ForceField]效果(https://www.jianshu.com/p/80a932d1f11e),与我想要的差不多,可是放进项目中发现无法正常显示,原来是正交投影的问题,后来在Kaima_Chen大的指点下,重写了LinearEyeDepth,完美解决。再然后就是去掉光罩,关掉背面剔除,大功告成。
使用方法很简单,创建一个球体(或者其他形状体),然后创建Material,设置为这个Shader就行了。
Shader "Custom/IntersectField"
{
Properties
{
_MainColor("Main Color", Color) = (1,1,1,1)
_IntersectionPower("Intersect Power", Range(0, 1)) = 0
}
SubShader
{
Tags { "Queue"="Transparent" "RenderType"="Transparent" }
Pass
{
ZWrite Off
Cull Off
Blend DstAlpha OneMinusSrcAlpha
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
};
struct v2f
{
float4 vertex : SV_POSITION;
float4 screenPos : TEXCOORD1;
};
sampler2D _CameraDepthTexture;
fixed4 _MainColor;
float _IntersectionPower;
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.screenPos = ComputeScreenPos(o.vertex);
COMPUTE_EYEDEPTH(o.screenPos.z);
return o;
}
float OrthoLinearEyeDepth(float z)
{
float far = _ProjectionParams.z;
float near = _ProjectionParams.y;
return z * (far - near) + near;
}
fixed4 frag (v2f i) : SV_Target
{
//透视投影用LinearEyeDepth,正交投影用OrthoLinearEyeDepth
float screenZ = OrthoLinearEyeDepth(SAMPLE_DEPTH_TEXTURE_PROJ(_CameraDepthTexture, UNITY_PROJ_COORD(i.screenPos)));
float diff = 1 - (screenZ - i.screenPos.z);
float intersect = diff * _IntersectionPower;
fixed4 c = _MainColor * intersect;
return c;
}
ENDCG
}
}
}