裁剪UI区域

作者:追风剑情 发布于:2018-12-19 11:30 分类:Shader

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);
	}
}


工程截图

111111.png

qqqq11111.pngqqqqq222222.png

运行效果

3333.png

标签: Shader

Powered by emlog  蜀ICP备18021003号   sitemap

川公网安备 51019002001593号