/// <summary>
    /// 除遮罩之外都填充
    /// </summary>
    /// <param name="_vh">顶点Helper</param>
    /// <param name="_masks">绘制组</param>
    protected virtual void OnFillExceptMask(VertexHelper _vh, List <AbsUIGuideGraphic> _masks)
    {
        #region 屏幕矩形
        GraphicRect2D sceneRect = new GraphicRect2D(-1, this);
        #endregion

        #region 遮罩矩形
        List <GraphicRect2D> maskRect = new List <GraphicRect2D>();
        GraphicRect2D        rect;
        for (int i = 0; i < _masks.Count; i++)
        {
            rect = new GraphicRect2D(i, _masks[i].graphic);
            maskRect.Add(rect);
        }

        //求两矩形填充点和矩形在屏幕上的填充点
        List <Vector3> useVertexs      = new List <Vector3>();
        List <Vector3> tempVertexs     = new List <Vector3>();
        List <Vector3> validateVertexs = new List <Vector3>();
        if (maskRect.Count <= 1)
        {
            tempVertexs = maskRect[0].IntersectionFill(sceneRect);
            if (tempVertexs.Count > 0)
            {
                validateVertexs.AddRange(tempVertexs);
            }
        }
        else
        {
            foreach (GraphicRect2D a in maskRect)
            {
                foreach (GraphicRect2D b in maskRect)
                {
                    tempVertexs = a.IntersectionFill(b);
                    if (tempVertexs.Count > 0)
                    {
                        validateVertexs.AddRange(tempVertexs);
                    }
                }
            }
        }
        #endregion

        validateVertexs.InsertRange(0, sceneRect.corners);

        #region 清理重复的点
        List <int> hasPoint = new List <int>();
        int        pk       = 0;
        Vector3    tp       = Vector3.zero;
        foreach (Vector3 cv in validateVertexs)
        {
            //顶点不超过屏幕
            tp.x = cv.x;
            tp.x = Mathf.Max(tp.x, sceneRect.rect.xMin);
            tp.x = Mathf.Min(tp.x, sceneRect.rect.xMax);
            tp.y = cv.y;
            tp.y = Mathf.Max(tp.y, sceneRect.rect.yMin);
            tp.y = Mathf.Min(tp.y, sceneRect.rect.yMax);
            //过滤重复点
            pk = (tp.x.ToString() + tp.y.ToString()).UniqueHashCode();
            if (!hasPoint.Contains(pk))
            {
                hasPoint.Add(pk);
                useVertexs.Add(tp);
            }
        }
        #endregion

        mDelaunayResult = Polygon2DUtility.BuilderDelaunay2D(useVertexs, new List <int>()
        {
            0, 1, 2, 3
        });

        #region 绘制三角面
        _vh.Clear();
        Vector4    uv           = (sprite != null) ? UnityEngine.Sprites.DataUtility.GetOuterUV(sprite) : Vector4.zero;
        UIVertex[] vertexs      = new UIVertex[mDelaunayResult.vertexs.Count];
        List <int> vertexIndexs = new List <int>();
        foreach (PolygonPoint2D p in mDelaunayResult.vertexs)
        {
            vertexs[p.index] = new UIVertex()
            {
                position = p.position, color = color, uv0 = Rect.PointToNormalized(sceneRect.rect, p.position)
            };
        }

        bool isInAnyRect = false;
        foreach (PolygonTriangle2D tri in mDelaunayResult.delaunayTriangle)
        {
            foreach (GraphicRect2D r in maskRect)
            {
                isInAnyRect =
                    Geometry2DUtility.IsPointInRect(tri.vertexs[0].position, r.rect) &&
                    Geometry2DUtility.IsPointInRect(tri.vertexs[1].position, r.rect) &&
                    Geometry2DUtility.IsPointInRect(tri.vertexs[2].position, r.rect);
                if (isInAnyRect)
                {
                    break;
                }
            }
            if (!isInAnyRect)
            {
                vertexIndexs.Add(tri.vertexs[0].index);
                vertexIndexs.Add(tri.vertexs[1].index);
                vertexIndexs.Add(tri.vertexs[2].index);
            }
        }
        _vh.AddUIVertexStream(new List <UIVertex>(vertexs), vertexIndexs);
        #endregion
    }
    /// <summary>
    /// 除遮罩之外都填充
    /// </summary>
    /// <param name="_sceneRect">屏幕矩形</param>
    /// <param name="_masks">绘制组</param>
    protected virtual void OnFillExceptMask(Rect _sceneRect, List <AbsUIGuideGraphic> _masks)
    {
        Sprite  sprite                     = null;
        Image   image                      = null;
        Vector4 spriteUVRatio              = Vector4.zero;
        Vector4 spriteUV                   = Vector4.zero;
        Vector4 spriteUVClip               = Vector4.zero;
        Vector4 spriteBorder               = Vector4.zero;
        Vector4 rectUV                     = Vector4.zero;
        Vector4 sceneGraphicWh             = Vector4.zero;
        Vector4 graphicRectSlicedBorder    = Vector4.zero;
        Vector4 graphicUvSlicedBorderRatio = Vector4.zero;
        Vector2 rectMin                    = Vector2.zero;
        Vector2 rectMax                    = Vector2.zero;
        bool    isGraphicSliced            = false;

        sceneGraphicWh.x = _sceneRect.size.x;
        sceneGraphicWh.y = _sceneRect.size.y;
        Rect maskRect = new Rect();

        for (int i = 0; i < _masks.Count; i++)
        {
            spriteUV         = uvDefault;
            spriteUVClip     = uvDefault;
            spriteBorder     = Vector4.zero;
            isGraphicSliced  = false;
            maskRect         = _masks[i].graphic.GraphicLocalRectForVertexHelper();
            sceneGraphicWh.z = maskRect.size.x;
            sceneGraphicWh.w = maskRect.size.y;
            rectMin          = Rect.PointToNormalized(_sceneRect, maskRect.min);
            rectMax          = Rect.PointToNormalized(_sceneRect, maskRect.max);
            rectUV.Set(rectMin.x, rectMin.y, rectMax.x, rectMax.y);

            if (!Geometry2DUtility.IsPointInRect(maskRect.min, _sceneRect))
            {
                if (rectMin.x == 0)
                {
                    spriteUVClip.x = Mathf.InverseLerp(maskRect.min.x, maskRect.max.x, _sceneRect.min.x);
                }
                if (rectMin.y == 0)
                {
                    spriteUVClip.y = Mathf.InverseLerp(maskRect.min.y, maskRect.max.y, _sceneRect.min.y);
                }
            }

            if (_masks[i].graphic is Image)
            {
                image  = (Image)_masks[i].graphic;
                sprite = image.overrideSprite;
                if (sprite != null)
                {
                    spriteUV = UnityEngine.Sprites.DataUtility.GetOuterUV(sprite);
                    Texture2D texSrc = sprite.texture;
                    spriteUVRatio.x = sprite.rect.x / texSrc.width;
                    spriteUVRatio.y = sprite.rect.y / texSrc.height;
                    spriteUVRatio.z = sprite.rect.width / texSrc.width;
                    spriteUVRatio.w = sprite.rect.height / texSrc.height;

                    graphicRectSlicedBorder.x = sprite.border.x / _masks[i].graphic.GetPixelAdjustedRect().width * 0.5f;
                    graphicRectSlicedBorder.y = sprite.border.y / _masks[i].graphic.GetPixelAdjustedRect().height * 0.5f;
                    graphicRectSlicedBorder.z = sprite.border.z / _masks[i].graphic.GetPixelAdjustedRect().width * 0.5f;
                    graphicRectSlicedBorder.w = sprite.border.w / _masks[i].graphic.GetPixelAdjustedRect().height * 0.5f;
                    graphicRectSlicedBorder.z = 1 - graphicRectSlicedBorder.z;
                    graphicRectSlicedBorder.w = 1 - graphicRectSlicedBorder.w;

                    graphicUvSlicedBorderRatio.x = sprite.border.x / sprite.textureRect.width;
                    graphicUvSlicedBorderRatio.y = sprite.border.y / sprite.textureRect.height;
                    graphicUvSlicedBorderRatio.z = sprite.border.z / sprite.textureRect.width;
                    graphicUvSlicedBorderRatio.w = sprite.border.w / sprite.textureRect.height;
                }
                switch (image.type)
                {
                case Image.Type.Sliced:
                case Image.Type.Tiled:
                    isGraphicSliced = true;
                    break;
                }
            }
            material.SetTexture("_GraphicTex" + i, _masks[i].graphic.mainTexture);
            material.SetVector("_GraphicUvSlicedBorderRatio" + i, graphicUvSlicedBorderRatio);
            material.SetVector("_SceneGraphicWh" + i, sceneGraphicWh);
            material.SetVector("_GraphicUvRatio" + i, spriteUVRatio);
            material.SetVector("_GraphicUvMinMax" + i, spriteUV);
            material.SetVector("_GraphicUvMinMaxClip" + i, spriteUVClip);
            material.SetVector("_GraphicUvMaskForScene" + i, rectUV);
            material.SetInt("_isGraphicSliced" + i, isGraphicSliced ? 1 : 0);
            material.SetVector("_GraphicRectSlicedBorder" + i, graphicRectSlicedBorder);
        }
    }