贴图九宫缩放

作者:追风剑情 发布于:2023-4-13 17:43 分类:Unity3d

1、创建九宫缩放Shader

//用于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
    }
}
}

2、创建九宫缩放脚本(非必须)

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

3、创建九宫缩放Material

11111.png

4、创建3个Quad

22222.png

给每个Quad设置不同的九宫缩放参数

4444.png

显示效果

33333.png

Powered by emlog  蜀ICP备18021003号-1   sitemap

川公网安备 51019002001593号