//用于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设置不同的九宫缩放参数
显示效果