Unity - 对象上具有抗锯齿功能的 2D 圆孔
Unity - 2D circle hole with antialiasing on object
我想在一个空物体内添加一个洞,里面有精灵。这个洞是圆形的。
为此,我将着色器添加到 material 并将 material 添加到 Sprite Renderer 组件到空对象。
这是我的着色器:
Shader "Sprite/Hole Effect"
{
Properties
{
_MainTex ("Base (RGB)", 2D) = "white" {}
_ObjPos ("Object Position", Vector) = (1,1,1,1)
_Cutoff ("Alpha cutoff", Range(0,1)) = 0.5
_Radius ("Hole Radius", Range(0.1,10)) = 2
}
SubShader
{
Pass
{
Cull Off
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
uniform sampler2D _MainTex;
float _Radius;
float4 _ObjPos;
struct vertexInput {
float4 vertex : POSITION;
float4 texcoord : TEXCOORD0;
};
struct vertexOutput {
float4 pos : SV_POSITION;
float4 worldPos : POSITION1;
float4 tex : TEXCOORD0;
};
vertexOutput vert(vertexInput input)
{
vertexOutput output;
output.tex = input.texcoord;
output.pos = UnityObjectToClipPos(input.vertex);
output.worldPos = mul(input.vertex, unity_ObjectToWorld);
return output;
}
float4 frag(vertexOutput input) : COLOR
{
float4 textureColor = tex2D(_MainTex, input.tex.xy);
float dis = distance(input.worldPos.xyz, _ObjPos);
if (dis > _Radius)
{
discard;
}
return textureColor;
}
ENDCG
}
}
FallBack "Diffuse"
}
这个方法的问题是圆没有抗锯齿...
所以我尝试给空对象添加一个Sprite蒙版,但是没有抗锯齿下层...
我认为着色器是实现该目标的良好解决方案,但我真的不知道该怎么做!
任何帮助都是完美的!!!
终于找到了!!
我将带有着色器的 material 应用于我想要看到圆圈的对象的精灵。
这是我的着色器:
Shader "Sprites/XRay Effect"
{
Properties
{
[PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
_PlayerPos ("Player Position", Vector) = (0,0,0,0)
_Radius ("Hole Radius", Range(0.1,100)) = 2
_Border ("Border", Range(0.001,1)) = 0.05
}
SubShader
{
Tags
{
"Queue"="Transparent"
"IgnoreProjector"="True"
"RenderType"="Transparent"
"PreviewType"="Plane"
"CanUseSpriteAtlas"="True"
}
Cull Off
Lighting Off
ZWrite Off
ZTest [unity_GUIZTestMode]
Blend SrcAlpha OneMinusSrcAlpha
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#include "UnityUI.cginc"
struct vertexInput
{
float4 vertex : POSITION;
float4 color : COLOR;
float2 texCoord : TEXCOORD0;
};
struct vertexOutput
{
float4 vertex : SV_POSITION;
fixed4 color : COLOR;
half2 texCoord : TEXCOORD0;
float3 worldPosition : TEXCOORD1;
};
sampler2D _MainTex;
float4 _PlayerPos;
float _Radius;
float _Border;
vertexOutput vert(vertexInput IN)
{
vertexOutput OUT;
OUT.vertex = UnityObjectToClipPos(IN.vertex);
OUT.texCoord = IN.texCoord;
OUT.worldPosition = mul(unity_ObjectToWorld, IN.vertex);
OUT.color = IN.color;
return OUT;
}
fixed4 frag(vertexOutput IN) : SV_Target
{
half4 color = tex2D(_MainTex, IN.texCoord) * IN.color;
// Adding the circle hole
float dis = distance(IN.worldPosition.xyz, _PlayerPos.xyz);
color.a = lerp(0, color.a, color.a * (dis - _Radius) / _Border);
return color;
}
ENDCG
}
}
FallBack "UI/Default"
}
您可以根据需要修改 lerp(0, color.a, color.a * (dis - _Radius) / _Border)
部分。
我想在一个空物体内添加一个洞,里面有精灵。这个洞是圆形的。
为此,我将着色器添加到 material 并将 material 添加到 Sprite Renderer 组件到空对象。
这是我的着色器:
Shader "Sprite/Hole Effect"
{
Properties
{
_MainTex ("Base (RGB)", 2D) = "white" {}
_ObjPos ("Object Position", Vector) = (1,1,1,1)
_Cutoff ("Alpha cutoff", Range(0,1)) = 0.5
_Radius ("Hole Radius", Range(0.1,10)) = 2
}
SubShader
{
Pass
{
Cull Off
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
uniform sampler2D _MainTex;
float _Radius;
float4 _ObjPos;
struct vertexInput {
float4 vertex : POSITION;
float4 texcoord : TEXCOORD0;
};
struct vertexOutput {
float4 pos : SV_POSITION;
float4 worldPos : POSITION1;
float4 tex : TEXCOORD0;
};
vertexOutput vert(vertexInput input)
{
vertexOutput output;
output.tex = input.texcoord;
output.pos = UnityObjectToClipPos(input.vertex);
output.worldPos = mul(input.vertex, unity_ObjectToWorld);
return output;
}
float4 frag(vertexOutput input) : COLOR
{
float4 textureColor = tex2D(_MainTex, input.tex.xy);
float dis = distance(input.worldPos.xyz, _ObjPos);
if (dis > _Radius)
{
discard;
}
return textureColor;
}
ENDCG
}
}
FallBack "Diffuse"
}
这个方法的问题是圆没有抗锯齿...
所以我尝试给空对象添加一个Sprite蒙版,但是没有抗锯齿下层...
我认为着色器是实现该目标的良好解决方案,但我真的不知道该怎么做!
任何帮助都是完美的!!!
终于找到了!!
我将带有着色器的 material 应用于我想要看到圆圈的对象的精灵。
这是我的着色器:
Shader "Sprites/XRay Effect"
{
Properties
{
[PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
_PlayerPos ("Player Position", Vector) = (0,0,0,0)
_Radius ("Hole Radius", Range(0.1,100)) = 2
_Border ("Border", Range(0.001,1)) = 0.05
}
SubShader
{
Tags
{
"Queue"="Transparent"
"IgnoreProjector"="True"
"RenderType"="Transparent"
"PreviewType"="Plane"
"CanUseSpriteAtlas"="True"
}
Cull Off
Lighting Off
ZWrite Off
ZTest [unity_GUIZTestMode]
Blend SrcAlpha OneMinusSrcAlpha
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#include "UnityUI.cginc"
struct vertexInput
{
float4 vertex : POSITION;
float4 color : COLOR;
float2 texCoord : TEXCOORD0;
};
struct vertexOutput
{
float4 vertex : SV_POSITION;
fixed4 color : COLOR;
half2 texCoord : TEXCOORD0;
float3 worldPosition : TEXCOORD1;
};
sampler2D _MainTex;
float4 _PlayerPos;
float _Radius;
float _Border;
vertexOutput vert(vertexInput IN)
{
vertexOutput OUT;
OUT.vertex = UnityObjectToClipPos(IN.vertex);
OUT.texCoord = IN.texCoord;
OUT.worldPosition = mul(unity_ObjectToWorld, IN.vertex);
OUT.color = IN.color;
return OUT;
}
fixed4 frag(vertexOutput IN) : SV_Target
{
half4 color = tex2D(_MainTex, IN.texCoord) * IN.color;
// Adding the circle hole
float dis = distance(IN.worldPosition.xyz, _PlayerPos.xyz);
color.a = lerp(0, color.a, color.a * (dis - _Radius) / _Border);
return color;
}
ENDCG
}
}
FallBack "UI/Default"
}
您可以根据需要修改 lerp(0, color.a, color.a * (dis - _Radius) / _Border)
部分。