zoukankan      html  css  js  c++  java
  • [UGUI]UI特效裁剪

    参考链接:

    https://blog.csdn.net/bn0305/article/details/78058076

    https://www.xuanyusong.com/archives/3518

    https://blog.csdn.net/wangjiangrong/article/details/79483257

    Mask组件的裁剪效果,只对其下的UI元素生效,且在绘制完其下的UI元素后,所在区域的模板缓冲值会恢复为0

    要想UI特效也被裁剪,可以计算scrollview四个点在世界坐标的位置,然后在粒子的shader中进行判断,如果在范围内则显示

    一.shader

    留意标记为add的部分

    Shader "Custom/Particles/AlphaBlendedMask" {
        Properties 
        {
            _MainTex ("Particle Texture", 2D) = "white" {}
    
            //----------------------------------------add--------------------------------
            _MinX("MinX", Float) = 0
            _MinY("MinY", Float) = 0
            _MaxX("MaxX", Float) = 0
            _MaxY("MaxY", Float) = 0
            //----------------------------------------add--------------------------------
        }
    
        SubShader 
        {
            Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" "PreviewType"="Plane" }
            Blend SrcAlpha OneMinusSrcAlpha
            Cull Off Lighting Off ZWrite Off Fog { Color (0,0,0,0) }
    
            Pass
            {
                CGPROGRAM
                #pragma vertex vert
                #pragma fragment frag
    
                #include "UnityCG.cginc"
    
                //----------------------------------------add--------------------------------
                float _MinX;
                float _MinY;
                float _MaxX;
                float _MaxY;
                //----------------------------------------add--------------------------------
    
                struct appdata
                {
                    float4 vertex : POSITION;
                    float2 uv : TEXCOORD0;
                };
    
                struct v2f
                {
                    float4 vertex : SV_POSITION;
                    float2 uv : TEXCOORD0;
    
                    //----------------------------------------add--------------------------------
                    float2 worldPos : TEXCOORD1;
                    //----------------------------------------add--------------------------------
                };
    
                sampler2D _MainTex;
                float4 _MainTex_ST;
    
                v2f vert (appdata v)
                {
                    v2f o;
                    o.vertex = UnityObjectToClipPos(v.vertex);
                    o.uv = TRANSFORM_TEX(v.uv, _MainTex);
    
                    //----------------------------------------add--------------------------------
                    o.worldPos = mul(unity_ObjectToWorld, v.vertex).xy;
                    //----------------------------------------add--------------------------------
    
                    return o;
                }
    
                fixed4 frag (v2f i) : SV_Target
                {
                    fixed4 col = tex2D(_MainTex, i.uv);
    
                    //----------------------------------------add--------------------------------
                    float posX = i.worldPos.x;
                    float posY = i.worldPos.y;
                    fixed result = step(_MinX, posX) * step(posX, _MaxX) * step(_MinY, posY) * step(posY, _MaxY);
                    return result * col + (1 - result) * fixed4(0, 0, 0, 0);
                    //----------------------------------------add--------------------------------
    
                    //return col;
                }
                ENDCG
            }
        }
    }

    二.c#

    计算scrollview四个点在世界坐标的位置

    using UnityEngine;
    
    public class UIHelper : CSharpSingletion<UIHelper>
    {
        //顺时针
        //1  2
        //0  3
        public Vector4 GetWorldCorners(GameObject go)
        {
            RectTransform rectTransform = go.GetComponent<RectTransform>();
            Vector3[] corners = new Vector3[4];
            rectTransform.GetWorldCorners(corners);
            float minX = corners[0].x;
            float minY = corners[0].y;
            float maxX = corners[2].x;
            float maxY = corners[2].y;
            return new Vector4(minX, minY, maxX, maxY);
        }
    }

    设置材质

    using UnityEngine;
    
    public class UIEffect : MonoBehaviour
    {
        Renderer[] renderers;
        MaterialPropertyBlock materialPropertyBlock;
    
        void Start()
        {
            renderers = gameObject.GetComponentsInChildren<Renderer>();
            materialPropertyBlock = new MaterialPropertyBlock();
        }
    
        public void SetMask(float minX, float minY, float maxX, float maxY)
        {
            for (int i = 0; i < renderers.Length; i++)
            {
                Renderer renderer = renderers[i];
                materialPropertyBlock.Clear();
                renderer.GetPropertyBlock(materialPropertyBlock);
                materialPropertyBlock.SetFloat("_MinX", minX);
                materialPropertyBlock.SetFloat("_MinY", minY);
                materialPropertyBlock.SetFloat("_MaxX", maxX);
                materialPropertyBlock.SetFloat("_MaxY", maxY);
                renderer.SetPropertyBlock(materialPropertyBlock);
            }
        }
    }

    效果如下:

  • 相关阅读:
    .net core + mvc 手撸一个代码生成器
    如何使用VS Code编写Spring Boot (第二弹)
    第五章 .net core该怎么玩
    第四章 .net core做一个简单的登录
    第三章 搭建一个通用的权限管理系统
    第二章 在Linux上部署.net core
    将博客搬至CSDN
    Entity Framework6 with Oracle(可实现code first)
    利用windbg查找dictionary导致IIS占CPU100%案例分析(一)
    VS快捷键以及Reshaper快捷键
  • 原文地址:https://www.cnblogs.com/lyh916/p/14883520.html
Copyright © 2011-2022 走看看