Shader代码
Shader "Custom/UIClipTest"
{
Properties
{
[PerRendererData]
_MainTex ("Texture", 2D) = "white" {}
[Toggle(UNITY_UI_CLIP_RECT)]
_UseUIClipRect ("Use Rect Clip", Float) = 1
[Toggle(UNITY_UI_ALPHACLIP)]
_UseUIAlphaClip ("Use Alpha Clip", Float) = 1
}
SubShader
{
LOD 100
Tags
{
"LightMode"="ForwardBase"
"Queue" = "Transparent"
"IgnoreProjector" = "True"
"RenderType" = "Transparent"
"PreviewType"="Plane"
}
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#include "UnityUI.cginc"
//定义宏
#pragma multi_compile __ UNITY_UI_CLIP_RECT
#pragma multi_compile __ UNITY_UI_ALPHACLIP
struct appdata
{
//世界坐标
float4 vertex : POSITION;
//纹理坐标
float2 uv : TEXCOORD0;
};
struct v2f
{
//裁剪空间坐标
float4 vertex : SV_POSITION;
//纹理坐标
float2 uv : TEXCOORD0;
//世界坐标
float4 worldPosition : TEXCOORD1;
};
sampler2D _MainTex;
float4 _MainTex_ST;
float4 _ClipRect;
v2f vert (appdata v)
{
v2f o;
o.worldPosition = v.vertex;
o.vertex = UnityObjectToClipPos(o.worldPosition);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
fixed4 col = tex2D(_MainTex, i.uv);
#ifdef UNITY_UI_CLIP_RECT
col.a *= UnityGet2DClipping(i.worldPosition.xy, _ClipRect);
#endif
#ifdef UNITY_UI_ALPHACLIP
clip (col.a - 0.001);
#endif
return col;
}
ENDCG
}
}
}
UnityGet2DClipping()方法在UnityUI.cginc文件中
#ifndef UNITY_UI_INCLUDED
#define UNITY_UI_INCLUDED
inline float UnityGet2DClipping (in float2 position, in float4 clipRect)
{
float2 inside = step(clipRect.xy, position.xy) * step(position.xy, clipRect.zw);
return inside.x * inside.y;
}
inline fixed4 UnityGetUIDiffuseColor(in float2 position, in sampler2D mainTexture, in sampler2D alphaTexture, fixed4 textureSampleAdd)
{
return fixed4(tex2D(mainTexture, position).rgb + textureSampleAdd.rgb, tex2D(alphaTexture, position).r + textureSampleAdd.a);
}
#endif
C#代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class UIClipTest : MonoBehaviour {
public Rect buttonRect = new Rect(0, 0, 400, 40);
public Vector4 clipRect;
public Texture2D mainTex;
public MeshRenderer meshRenderer;
void Start () {
meshRenderer = this.GetComponent<MeshRenderer>();
}
void OnGUI () {
if (GUI.Button(buttonRect, "Clip")) {
SetColorPropertyBlock(meshRenderer);
}
}
private void SetColorPropertyBlock(Renderer renderer)
{
//这种方式不会创建新的Material
MaterialPropertyBlock properties = new MaterialPropertyBlock();
properties.SetTexture(
"_MainTex", mainTex
);
properties.SetVector(
"_ClipRect", clipRect
);
renderer.SetPropertyBlock(properties);
}
}
工程截图
运行效果