//用于Quad Mesh贴图 九宫缩放 Shader "Unlit/Transparent (9Palace Zoom)" { Properties { [NoScaleOffset] _MainTex ("Base (RGB) Trans (A)", 2D) = "white" {} //左边距 _L("Border L", Range(0, 0.5)) = 0.2 //右边距 _R("Border R", Range(0, 0.5)) = 0.2 //上边距 _T("Border T", Range(0, 0.5)) = 0.2 //下边距 _B("Border B", Range(0, 0.5)) = 0.2 //针对四个角的缩放值 _ScaleX("Scale X", Float) = 1 _ScaleY("Scale Y", Float) = 1 } SubShader { Tags {"Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent"} LOD 100 ZWrite Off Blend SrcAlpha OneMinusSrcAlpha Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #pragma target 2.0 #pragma multi_compile_fog #include "UnityCG.cginc" struct appdata_t { float4 vertex : POSITION; float2 texcoord : TEXCOORD0; UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { float4 vertex : SV_POSITION; float2 texcoord : TEXCOORD0; UNITY_FOG_COORDS(1) UNITY_VERTEX_OUTPUT_STEREO }; sampler2D _MainTex; float4 _MainTex_ST; fixed _L; fixed _R; fixed _T; fixed _B; fixed _ScaleX; fixed _ScaleY; v2f vert (appdata_t v) { v2f o; UNITY_SETUP_INSTANCE_ID(v); UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); o.vertex = UnityObjectToClipPos(v.vertex); o.texcoord = TRANSFORM_TEX(v.texcoord, _MainTex); UNITY_TRANSFER_FOG(o,o.vertex); return o; } fixed4 frag (v2f i) : SV_Target { fixed2 uv = i.texcoord; //将原来的Border尺寸进行缩放 fixed _sL = _L * _ScaleX; fixed _sR = _R * _ScaleX; fixed _sT = _T * _ScaleY; fixed _sB = _B * _ScaleY; //通过插值算法将四个角的画面进行缩放 //插值比例 fixed _wL = uv.x / _sL; fixed _wR = (uv.x - (1 - _sR)) / _sR; fixed _wT = uv.y / _sT; fixed _wB = (uv.y - (1 - _sB)) / _sB; //对x坐标插值 /* 普通算法 if (uv.x < _sL) // step(uv.x, _sL); uv.x = lerp(0, _L, _wL); else if (uv.x > 1 - _sR) //step(1-_sR, uv.x) uv.x = lerp(1 - _R, 1, _wR); else uv.x = 0.5; //step(_sL, uv.x) * step(uv.x, 1-_sR); */ //优化算法 uv.x = lerp(0, _L, _wL) * step(uv.x, _sL) + lerp(1 - _R, 1, _wR) * step(1 - _sR, uv.x) + 0.5 * step(_sL, uv.x) * step(uv.x, 1 - _sR); //对y坐标插值 /* 普通算法 if (uv.y < _sT) uv.y = lerp(0, _T, _wT); else if (uv.y > 1 - _sT) uv.y = lerp(1 - _B, 1, _wB); else uv.y = 0.5; */ //优化算法 uv.y = lerp(0, _T, _wT) * step(uv.y, _sT) + lerp(1 - _B, 1, _wB) * step(1 - _sB, uv.y) + 0.5 * step(_sT, uv.y) * step(uv.y, 1 - _sB); //End fixed4 col = tex2D(_MainTex, uv); UNITY_APPLY_FOG(i.fogCoord, col); return col; } ENDCG } } }
using UnityEngine; [ExecuteInEditMode] public class Transparent9PalaceZoom : MonoBehaviour { [SerializeField] private MeshRenderer meshRenderer; [SerializeField] private Texture2D mainTexture; [SerializeField] private float borderL = 0.2f; [SerializeField] private float borderR = 0.2f; [SerializeField] private float borderT = 0.2f; [SerializeField] private float borderB = 0.2f; [SerializeField] private float scaleX = 1; [SerializeField] private float scaleY = 1; [SerializeField] private bool m_Update = false; private void Update() { if (!m_Update) return; m_Update = false; //更新材质属性值 if (meshRenderer == null) meshRenderer = this.GetComponent<MeshRenderer>(); if (meshRenderer == null) return; MaterialPropertyBlock properties = new MaterialPropertyBlock(); if (mainTexture != null) properties.SetTexture("_MainTex", mainTexture); properties.SetFloat("_L", borderL); properties.SetFloat("_R", borderR); properties.SetFloat("_T", borderT); properties.SetFloat("_B", borderB); properties.SetFloat("_ScaleX", scaleX); properties.SetFloat("_ScaleY", scaleY); meshRenderer.SetPropertyBlock(properties); } }
给每个Quad设置不同的九宫缩放参数
显示效果